角度指令模板输入不会更新指令范围
Angular directive template input doesn't update directive scope
我有一个具有隔离作用域的自定义指令,在它的link
函数中,我正在设置一些额外的作用域变量,例如:
templateUrl:"chat.html",
scope:{},
link: function (scope, element, attrs) {
scope.chat;
scope.send_txt="";
scope.use_enter = false;
scope.other;
在我的chat.html
我有一个输入元素,例如
....
...
<textarea ng-model="send_txt" class="form-control" placeholder="Message..." aria-describedby="basic-addon1" style="border:2px solid #0079BE; border-radius:5px;margin-bottom:5px;"></textarea>
...
通常,当我在链接中设置scope.send_txt
时,该值会正确反映在文本区域中,但是一旦我在文本区域中键入某些内容,scope.send_txt
变量就会停止更新,就好像文本区域现在有自己的范围一样。知道问题可能是什么吗?
编辑:
命令:
'use strict';
angular.module('chatApp')
.directive('chatpane', [
'$http',
'socket',
'message',
'$mdDialog',
'$mdMedia',
function ($http,socket,message,$mdDialog,$mdMedia) {
return {
templateUrl: 'app/dashboard/message/chatpane/chatpane.html',
restrict: 'E',
scope:{
thread : "=thread",
owner : "=owner",
},
link: function (scope, element, attrs) {
/*console.log("chat: ",nv, " : ",ov);*/
scope.chat;
scope.send_txt="";
scope.use_enter = false;
scope.other;
scope.$watch("thread",function(nv,ov,scope){
if(nv){
$http.get('api/messages/threads/'+nv._id+'/0').then(function(d){
scope.chat = d.data;
scope.other = (scope.owner!=scope.thread.owner._id)?scope.thread.owner._id:scope.thread.recipient._id;
//mark thread read
message.markThreadRead(scope.thread._id);
})
}
},true);
scope.$watch("send_txt",function(nv,ov,scope){
console.log("chat: ",nv, " : ",ov);
},true);
scope.$watch('chat', function(newValue, oldValue, scope) {
if(element.find('.msg_inbox_msgs').length>0){
element.find('.msg_inbox_msgs').stop(true,true).animate({scrollTop:(element.find('.msg_inbox_msgs')[0].scrollHeight+(element.find('.msg_inbox_msgs>div').length*20))+'px'}, 1000);
}
});
scope.post = function(txt){
var tmp = txt || scope.send_txt;
scope.send_txt = "";
console.log("Posting: ",scope.send_txt);
if(tmp && _.trim(tmp)!=""){
$http.post('api/messages',{message:tmp, owner:scope.owner, recipient:scope.other, parent: scope.thread._id}).then(function(d){
//scope.chat.push(d.data);
//console.log("Response: ",d);
//console.log("chat: ",scope.chat);
});
}else{
console.log("Posting: ",scope.send_txt);
}
}
scope.acceptReferralRequest = function() {
$http.post('api/messages/acceptReferralRequest/'+scope.thread._id).then(function(d){
scope.thread.status = "accepted";
});
}
scope.ignoreReferralRequest = function() {
$http.post('api/messages/ignoreReferralRequest/'+scope.thread._id).then(function(d){
scope.thread.status = "ignored";
});
}
element.bind("keydown keypress", function (event) {
if(event.which === 13 && scope.use_enter) {
scope.post();
event.preventDefault();
}
});
scope.refer = function(ev){
var my_connections = [];
$http.get('api/users/get-all-connections').then(function(d){
for(var i in d.data){
var ii = _.findIndex(my_connections,{'_id':d.data[i]._id});
if(ii!=-1){
if(my_connections[ii].relation.indexOf(d.data[i].relation) == -1){
my_connections[ii].relation = my_connections[ii].relation +", "+d.data[i].relation;
}
}else{
my_connections.push(d.data[i]);
}
}
//show popup
var useFullScreen = ($mdMedia('sm') || $mdMedia('xs'));
$mdDialog.show({
controller: function(scope,$mdDialog){
scope.connections = my_connections;
scope.heading = "Refer";
scope.isAuthorized = true;
scope.cancel = function(){
$mdDialog.cancel();
};
scope.hide = function(user_url){
$mdDialog.hide(user_url);
}
},
templateUrl: 'app/dashboard/message/chatpane/refer.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: useFullScreen
})
.then(function(user_url) {
if(scope.send_txt && scope.send_txt!=""){
scope.send_txt += " #"+user_url+" ";
}else{
scope.send_txt = "I would like to recommend #"+user_url+" ";
}
}, function() {
scope.status = 'You cancelled the dialog.';
})
});
};
var handleSelf = function(d){
if((d.parent == scope.thread._id) && scope.owner==d.owner._id){
scope.chat.push(d);
}
//console.log("socket self: ",d);
};
socket.socket.removeListener('message:posted',handleSelf);
socket.socket.on('message:posted',handleSelf);
var handleRemote = function(d){
if((d.parent == scope.thread._id) && scope.owner==d.recipient._id){
scope.chat.push(d);
}
//console.log("socket remote: ",d);
};
socket.socket.removeListener('message:unread',handleRemote);
socket.socket.on('message:unread',handleRemote);
}
};
}]);
模板:
{{send_txt}}<div class="msg_inbox_cont" flex="column" flex layout-align="start stretch" ng-if="thread.group!='ask_referral'">
<div class="msg_inbox_head" flex ng-if="thread.title">
<div class="msg_topic_img col-sm-1 col-xs-3">
<img ng-src="api/images/{{msg.currentThread.owner.profile_pic || 'default.png' }}" alt="" width="30"/>
</div>
<div class="msg_topic_header col-sm-10 col-xs-9">
{{ thread.title}}
</div>
<div class="msg_topic_desc col-sm-10 col-xs-9">
{{ thread.message | limitTo:20 }}
</div>
</div>
<div class="msg_inbox_msgs" flex>
<div ng-class="ch.owner._id == owner ? 'msg_inbox_msg mine' : 'msg_inbox_msg other'" ng-repeat="(key, ch) in chat">
{{ch.message}}
</div>
</div>
<div class="msg_inbox_input" flex>
<div class="input-group">
<textarea ng-model="send_txt" class="form-control" placeholder="Message..." aria-describedby="basic-addon1" style="border:2px solid #0079BE; border-radius:5px;margin-bottom:5px;"></textarea>
</div>
<span><input type="checkbox" ng-model="use_enter" style="vertical-align: text-top;" /> Submit on enter</span>
<input type="button" ng-if='send_txt' class="pull-right btn btn-default btn-primary" ng-click="post()" value="Send"/>
<input type="button" ng-if='!send_txt' class="pull-right btn btn-default btn-disabled" disabled value="Send"/>
</div>
</div>
<!-- Ask Referral -->
<div class="msg_inbox_cont" flex="column" flex layout-align="start stretch" ng-if="thread.group=='ask_referral'">
<div class="msg_inbox_head" flex ng-if="thread.owner._id!=owner">
<div class="msg_topic_img col-sm-1 col-xs-3">
<img ng-src="api/images/{{thread.owner.profile_pic || 'default.png' }}" alt="" width="30"/>
</div>
<div class="msg_topic_header col-sm-10 col-xs-9">
{{ thread.owner.name }}
</div>
<div class="msg_topic_desc col-sm-10 col-xs-9">
has asked for a referral
</div>
</div>
<div class="msg_inbox_head" flex ng-if="thread.owner._id==owner">
<div class="msg_topic_img col-sm-1 col-xs-3">
<img ng-src="api/images/{{thread.owner.profile_pic || 'default.png' }}" alt="" width="30"/>
</div>
<div class="msg_topic_header col-sm-10 col-xs-9">
You
</div>
<div class="msg_topic_desc col-sm-10 col-xs-9">
have asked for a referral
</div>
</div>
<!-- accepted -->
<div class="msg_inbox_msgs" flex ng-if="thread.status=='accepted'">
<div ng-class="ch.owner._id == owner ? 'msg_inbox_msg mine' : 'msg_inbox_msg other'" ng-repeat="(key, ch) in chat">
{{ch.message}}
</div>
</div>
<!-- accepted -->
<!-- available / pending acceptance -->
<div class="msg_inbox_msgs" flex ng-if="thread.status=='available'">
<div ng-class="ch.owner._id == owner ? 'msg_inbox_msg mine' : 'msg_inbox_msg other'" ng-repeat="(key, ch) in chat">
{{ch.message}}
</div>
<div style="clear:both;" ng-if="thread.owner._id!=owner">
<input style="margin:10px;" type="button" class="pull-left btn btn-primary" value="Accept" ng-click="acceptReferralRequest()"/>
<input style="margin:10px;" type="button" class="pull-left btn btn-warning" value="Ignore" ng-click="ignoreReferralRequest()"/>
</div>
</div>
<!-- available / pending acceptance -->
<!-- available / pending acceptance -->
<div class="msg_inbox_msgs" flex ng-if="thread.status=='ignored'">
<div ng-class="ch.owner._id == owner ? 'msg_inbox_msg mine' : 'msg_inbox_msg other'" ng-repeat="(key, ch) in chat">
{{ch.message}}
</div>
<div style="clear:both;text-align:center;">
<span style="color:#5e5e5e;font-weight:bold;"><small><em>- Request has been ignored -</em></small></span>
</div>
</div>
<!-- available / pending acceptance -->
<div class="msg_inbox_input" flex ng-if="thread.status=='accepted'">
<div class="input-group">
<textarea ng-model="send_txt" class="form-control" placeholder="Message..." aria-describedby="basic-addon1" style="border:2px solid #0079BE; border-radius:5px;margin-bottom:5px;"></textarea>
</div>
<span><input type="checkbox" ng-model="use_enter" style="vertical-align: text-top;" /> Submit on enter</span>
<input type="button" ng-if='send_txt' class="pull-right btn btn-default btn-primary" ng-click="post(send_txt)" value="Send"/>
<input type="button" ng-if='!send_txt' class="pull-right btn btn-default btn-disabled" disabled value="Send"/>
<input type="button" ng-if='thread.owner._id!=owner' class="pull-right btn btn-default btn-primary" ng-click="refer($event)" value="Refer"/>{{send_txt}}
</div>
</div>
<!-- Ask Referral -->
你应该总是有一个.
,随着新作用域的引入,ng-model
或奇怪的事情可能会发生......
https://github.com/angular/angular.js/wiki/Understanding-Scopes
如规范中指定:
第一 ngModel will try to bind to the property given by evaluating the expression on the current scope. If the property doesn't already exist on this scope, it will be created implicitly and added to the scope.
第二: By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) or collections (e.g. arrays). If only properties of the object or collection change, ngModel will not be notified and so the input will not be re-rendered.
因此,如果您直接引用,您的引用可能会"丢失",这不会发生在.
中......
尝试:
templateUrl:"chat.html",
scope:{},
link: function (scope, element, attrs) {
scope.info = {
send_txt: ""
};
和
<textarea ng-model="info.send_txt" class="form-control" placeholder="Message..."
aria-describedby="basic-addon1" style="border:2px solid #0079BE;
border-radius:5px;margin-bottom:5px;"></textarea>
- 对父作用域的指令更新延迟了一步
- 我无法通过angularjs中的指令更新变量
- AngularJs 指令更新
- 如何在事件上对jquery上的ng模型进行指令更新
- 可以从控制器更新工厂,但不能从指令更新
- Angular指令更新多个元素的高度以匹配最高的
- Angular.js-从指令更新父作用域
- Angularjs 指令更新到 DOM 属性值的变化
- 从使用它的指令更新服务
- 推送到数组不会通过ng repeat指令更新视图列表
- AngularJS-通过服务从指令更新控制器数据(this.model语法)
- 如何让AngularJS指令更新由另一个指令生成的锚点
- 如何使用选择列表从指令更新父级上的模型
- 根据AngularJS中$apply或$digest循环的指令更新模型
- 从指令更新作用域,并使用另一个指令进行监视
- 通过指令更新作用域.最佳实践
- AngularJS后台任务指令更新控制器
- Angular指令更新父控制器对象
- 美元范围.父母.messageContent=值没有从指令更新父作用域
- AngularJS:通过指令更新模板绑定