javascript AngularJs 指令中的数据绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13688852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Data binding inside AngularJs directive
提问by Dustin
I am having a hard time figuring out how to make sure I maintain 2-way data binding when I create directives. Here is what I am working with and the fiddle:
我很难弄清楚如何确保在创建指令时保持 2 向数据绑定。这是我正在使用的和小提琴:
http://jsfiddle.net/dkrotts/ksb3j/6/
http://jsfiddle.net/dkrotts/ksb3j/6/
HTML:
HTML:
<textarea my-maxlength="20" ng-model="bar"></textarea>
<h1>{{bar}}</h1>
Directive:
指示:
myApp.directive('myMaxlength', ['$compile', function($compile) {
return {
restrict: 'A',
scope: {},
link: function (scope, element, attrs, controller) {
element = $(element);
var counterElement = $compile(angular.element('<span>Characters remaining: {{charsRemaining}}</span>'))(scope);
element.after(counterElement);
scope.charsRemaining = parseInt(attrs.myMaxlength);
scope.onEdit = function() {
var maxLength = parseInt(attrs.myMaxlength),
currentLength = parseInt(element.val().length);
if (currentLength >= maxLength) {
element.val(element.val().substr(0, maxLength));
scope.charsRemaining = 0;
} else {
scope.charsRemaining = maxLength - currentLength;
}
scope.$apply(scope.charsRemaining);
}
element.keyup(scope.onEdit)
.keydown(scope.onEdit)
.focus(scope.onEdit)
.live('input paste', scope.onEdit);
element.on('ngChange', scope.onEdit);
}
}
}]);
As I type in the textarea, the model is not updating like I need it to. What am I doing wrong?
当我在 textarea 中输入时,模型并没有像我需要的那样更新。我究竟做错了什么?
回答by Andre Goncalves
Well, there are two reasons why the two-way databinding doesn't work. First, you need to create a bi-directional binding between a local scope property and the parent scope property:
那么,双向数据绑定不起作用有两个原因。首先,您需要在本地作用域属性和父作用域属性之间创建双向绑定:
scope: { bar: "=ngModel" }
otherwise you're creating an isolated scope (see http://docs.angularjs.org/guide/directive).
否则,您将创建一个独立的范围(请参阅http://docs.angularjs.org/guide/directive)。
The other reason is that you have to replace the after insert instruction with an append from the parent (because you are only bootstrapping angular on dom.ready):
另一个原因是您必须用来自父级的附加指令替换 after insert 指令(因为您只是在 dom.ready 上引导 angular):
element.parent().append(counterElement);
Update jsfiddle: http://jsfiddle.net/andregoncalves/ksb3j/9/
更新 jsfiddle:http: //jsfiddle.net/andregoncalves/ksb3j/9/
回答by jaime
Do you really need a custom directive? AngularJS ships with a ngMaxlength
directive that combined with ngChange
might help you.
你真的需要自定义指令吗?AngularJS 附带了一个ngMaxlength
指令,结合使用ngChange
可能会对您有所帮助。
For example, if you have the following HTML
例如,如果您有以下 HTML
<body ng-controller="foo">
<form name="myForm">
<textarea name = "mytextarea"
ng-maxlength="20"
ng-change="change()"
ng-model="bar"></textarea>
<span class="error" ng-show="myForm.mytextarea.$error.maxlength">
Too long!
</span>
<span> {{left}} </span>
<h1>{{bar}}</h1>
</form>
</body>
Then you just need this into your controller
然后你只需要这个到你的控制器中
function foo($scope) {
$scope.change = function(){
if($scope.bar){
$scope.left = 20 - $scope.bar.length;
}else{
$scope.left = "";
}
};
$scope.bar = 'Hello';
$scope.change();
}
Let angular handle the dom as much as you can.
让 angular 尽可能多地处理 dom。
Here's the updated jsfiddle: http://jsfiddle.net/jaimem/ksb3j/7/
这是更新的 jsfiddle:http: //jsfiddle.net/jaimem/ksb3j/7/
回答by Flavio Oliveira
i'm not entirely sure, but i think that what you whant is a filter, take a look to this url, maybe it is a great approach to rethink about your problem.
我不完全确定,但我认为你想要的是过滤器,看看这个 url,也许这是重新思考你的问题的好方法。