我在同一元素上有一个元素指令(e-dir
)和一个属性指令(a-dir
):
<e-dir a-dir attr="msg"></e-dir>
我通过msg
属性将e-dir
传递到attr
的隔离范围:
app.directive('eDir', function eDir($timeout) {
return {
restrict: 'E',
scope: {
attr: '='
}
};
});
通过这种方式,msg
与$scope.attr
(EDirCtrl
)或scope.attr
(e-dir
的链接功能绑定(双向) )。
有一种简单的方法可以在a-dir
的指令中实现相同的双向数据绑定吗?或者你会推荐另一种更简单的方法吗?
我能够提出的最接近的事情是在eDirCtrl.attr = $scope.attr;
的控制器(e-dir
)内设置EDirCtrl
:
app.directive('eDir', function eDir($timeout) {
return {
restrict: 'E',
scope: {
attr: '='
},
controller: function EDirCtrl($scope) {
var eDirCtrl = this;
eDirCtrl.attr = $scope.attr;
},
controllerAs: 'eDirCtrl'
};
});
然后,让a-dir
需要e-dir
,并通过attr
的控制器(e-dir
)访问eDirCtrl.attr
:
app.directive('aDir', function aDir($timeout) {
return {
restrict: 'A',
require: 'eDir',
link: linkFn
};
function linkFn(scope, element, attrs, eDirCtrl) {
eDirCtrl.attr = 'eDirCtrl.attr';
}
});
但是,它不是双向的。正如您可以看到此代码段:
var app = angular.module('app', []);
app.controller('Ctrl', function Ctrl($scope) {
$scope.msg = 'initial message';
})
app.directive('eDir', function eDir($timeout) {
return {
restrict: 'E',
scope: {
attr: '='
},
template: '<div>$scope.attr: {{attr}}</div>'+
'<div>eDirCtrl.attr: {{eDirCtrl.attr}}</div>',
controller: function EDirCtrl($scope) {
var eDirCtrl = this;
eDirCtrl.attr = $scope.attr;
$timeout(function() {
$scope.attr = 'changing $scope.attr also changes msg';
}, 2000);
},
controllerAs: 'eDirCtrl'
};
});
app.directive('aDir', function aDir($timeout) {
return {
restrict: 'A',
require: 'eDir',
link: linkFn
};
function linkFn(scope, element, attrs, eDirCtrl) {
$timeout(function() {
eDirCtrl.attr = 'changing eDirCtrl.attr does not effect $scope.attr or msg';
}, 4000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl">
msg: <input type="text" ng-model="msg"><br>
<e-dir a-dir attr="msg"></e-dir>
</div>
答案 0 :(得分:2)
双向绑定不起作用的原因是attr
被绑定到字符串而不是对象。在JavaScript中,基元(布尔值,数字,字符串)是不可变的,因此当您更改一个时,前一个实例将被丢弃并使用一个新实例。这会破坏Angular的双向绑定,对scope.msg
的任何更改都不会通过attr
传播到指令中。
您可以通过在对象上设置msg
来按预期工作scope.test.msg
并将attr
绑定到test
(对象),而不是msg
(字符串)。
我已更新您的代码段以执行此操作:
var app = angular.module('app', []);
app.controller('Ctrl', function Ctrl($scope) {
$scope.test = {msg : 'initial message'};
})
app.directive('eDir', function eDir($timeout) {
return {
restrict: 'E',
scope: {
attr: '='
},
template: '<div>$scope.attr: {{attr.msg}}</div>'+
'<div>eDirCtrl.attr: {{eDirCtrl.attr.msg}}</div>',
controller: function EDirCtrl($scope) {
var eDirCtrl = this;
eDirCtrl.attr = $scope.attr;
$timeout(function() {
$scope.attr.msg = 'changing $scope.attr also changes msg';
}, 2000);
},
controllerAs: 'eDirCtrl'
};
});
app.directive('aDir', function aDir($timeout) {
return {
restrict: 'A',
require: 'eDir',
link: linkFn
};
function linkFn(scope, element, attrs, eDirCtrl) {
$timeout(function() {
eDirCtrl.attr.msg = 'changing eDirCtrl.attr does not effect $scope.attr or msg';
}, 4000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl">
msg: <input type="text" ng-model="test.msg"><br>
<e-dir a-dir attr="test"></e-dir>
</div>