I am struggling with data binding in AngularJs.
我正在和AngularJs中的数据绑定做斗争。
I have the following piece of markup in .html file that includes the custom directive:
我在.html文件中有如下标记,其中包含自定义指令:
<my-directive ng-repeat="i in object" attr-1="{{i.some_variable}}"></my-directive>
Note: 'some-variable' is being updated every 10 seconds(based on the associate collection and passed to template through controller).
注意:“some-variable”每10秒更新一次(基于关联集合并通过控制器传递给template)。
The directive's code includes:
该指令的代码包括:
myApp.directive('myDirective', function () {
scope: {
'attr-1': '=attr1'
which throws this exception because of the brackets in attr-1(see html code above).
由于attr1中的括号(参见上面的html代码),引发了这个异常。
It works though if I use read-only access(note at sign below):
如果我使用只读访问(请注意下面的符号):
myApp.directive('myDirective', function () {
scope: {
'attr-1': '@attr1'
I use scope.attr-1 in directive's HTML to show its value.
我使用范围。在指令的HTML中显示它的值。
The problem is that with read-only access UI is not reflecting the change in attribute change.
问题是,使用只读访问UI并不反映属性更改中的更改。
I've found solution with $parse or $eval(couldn't make them work tho). Is there a better one there?
我找到了$parse或$eval的解决方案(无法让它们工作)。有更好的吗?
2 个解决方案
#1
3
You'll need only two-way binding and I think $parse
or $eval
is not needed.
您只需要双向绑定,我认为不需要$parse或$eval。
Please have a look at the demo below or in this fiddle.
请看看下面的演示或在这个小提琴。
It uses $interval
to simulate your updating but the update can also come from other sources e.g. web socket or ajax request.
它使用$interval来模拟更新,但是更新也可以来自其他来源,例如web套接字或ajax请求。
I'm using controllerAs
and bindToController
syntax (AngularJs version 1.4 or newer required) but the same is also possible with just an isolated scope. See guide in angular docs.
我正在使用controllerAs和bindToController语法(AngularJs版本1.4或更新的required),但仅在一个独立的范围内也可以实现相同的功能。请参阅《角文档指南》。
The $watch
in the controller of the directive is only to show how the directive can detect that the data have changed.
该指令的控制器中的$watch只是用来显示该指令如何检测数据发生了变化。
angular.module('demoApp', [])
.controller('MainController', MainController)
.directive('myDirective', myDirective);
function MainController($interval) {
var self = this,
refreshTime = 1000; //interval time in ms
activate();
function activate() {
this.data = 0;
$interval(updateView, refreshTime);
}
function updateView() {
self.data = Math.round(Math.random()*100, 0);
}
}
function myDirective() {
return {
restrict: 'E',
scope: {
},
bindToController: {
data: '='
},
template: '<div><p>directive data: {{directiveCtrl.data}}</p></div>',
controller: function($scope) {
$scope.$watch('directiveCtrl.data', function(newValue) {
console.log('data changed', newValue);
});
},
controllerAs: 'directiveCtrl'
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController as ctrl">
model value in ctrl. {{ctrl.data}}
<my-directive data="ctrl.data"></my-directive>
</div>
#2
0
I've come to the following solution(in case somebody runs into the the same problem):
我想到了下面的解决方案(万一有人遇到同样的问题):
// Directive's code
myApp.directive('myDir', function () { return {
restrict: 'E',
templateUrl: function () {
return 'my-dir.html';
},
scope: {
'id': '@arId',
'x': '@arX',
'y': '@arY',
//....
},
link: function ($scope, element, attrs) {
// *** SOLUTION ***
attrs.$observe('arId', function (id) {
$scope.id = id;
});
//...
}
Update: somebody sent me this answer, they have the same problem and came up with a very similar if not exact same solution:
更新:有人给我发了这个答案,他们有同样的问题,并提出了一个非常相似的,如果不是完全相同的解决方案:
Using a directive inside an ng-repeat, and a mysterious power of scope '@'
在ng-repeat中使用指令,以及范围的神秘力量“@”
It is useful to read because they explain what's the idea behind it.
这是很有用的,因为他们解释了背后的想法。
#1
3
You'll need only two-way binding and I think $parse
or $eval
is not needed.
您只需要双向绑定,我认为不需要$parse或$eval。
Please have a look at the demo below or in this fiddle.
请看看下面的演示或在这个小提琴。
It uses $interval
to simulate your updating but the update can also come from other sources e.g. web socket or ajax request.
它使用$interval来模拟更新,但是更新也可以来自其他来源,例如web套接字或ajax请求。
I'm using controllerAs
and bindToController
syntax (AngularJs version 1.4 or newer required) but the same is also possible with just an isolated scope. See guide in angular docs.
我正在使用controllerAs和bindToController语法(AngularJs版本1.4或更新的required),但仅在一个独立的范围内也可以实现相同的功能。请参阅《角文档指南》。
The $watch
in the controller of the directive is only to show how the directive can detect that the data have changed.
该指令的控制器中的$watch只是用来显示该指令如何检测数据发生了变化。
angular.module('demoApp', [])
.controller('MainController', MainController)
.directive('myDirective', myDirective);
function MainController($interval) {
var self = this,
refreshTime = 1000; //interval time in ms
activate();
function activate() {
this.data = 0;
$interval(updateView, refreshTime);
}
function updateView() {
self.data = Math.round(Math.random()*100, 0);
}
}
function myDirective() {
return {
restrict: 'E',
scope: {
},
bindToController: {
data: '='
},
template: '<div><p>directive data: {{directiveCtrl.data}}</p></div>',
controller: function($scope) {
$scope.$watch('directiveCtrl.data', function(newValue) {
console.log('data changed', newValue);
});
},
controllerAs: 'directiveCtrl'
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController as ctrl">
model value in ctrl. {{ctrl.data}}
<my-directive data="ctrl.data"></my-directive>
</div>
#2
0
I've come to the following solution(in case somebody runs into the the same problem):
我想到了下面的解决方案(万一有人遇到同样的问题):
// Directive's code
myApp.directive('myDir', function () { return {
restrict: 'E',
templateUrl: function () {
return 'my-dir.html';
},
scope: {
'id': '@arId',
'x': '@arX',
'y': '@arY',
//....
},
link: function ($scope, element, attrs) {
// *** SOLUTION ***
attrs.$observe('arId', function (id) {
$scope.id = id;
});
//...
}
Update: somebody sent me this answer, they have the same problem and came up with a very similar if not exact same solution:
更新:有人给我发了这个答案,他们有同样的问题,并提出了一个非常相似的,如果不是完全相同的解决方案:
Using a directive inside an ng-repeat, and a mysterious power of scope '@'
在ng-repeat中使用指令,以及范围的神秘力量“@”
It is useful to read because they explain what's the idea behind it.
这是很有用的,因为他们解释了背后的想法。