我有一个带有隔离范围的指令。我正在修改从指令控制器中的父控制器传递的一个变量。我遇到的问题是,当我在同一视图上使用此指令的多个实例(具有不同的options
和model
)时,options
对象不会保持唯一指令的实例。相反,它成为共享变量,指令的所有实例都使用相同的options
对象。
因此,如果我在我的视图中使用过它们,请使用optionsA.isFlagOn = true
和optionsB.isFlagOn = false
<my-directive model="modelA" options="optionsA">
<my-directive model="modelB" options="optionsB">
带modelB
的{{1}}指令加载optionsA
。
如何为每个特定实例修改options
时保持唯一性?
angular.module('myModule', [])
.directive('myDirective', function($compile) {
template = '<h3><span ng-bind="model.title"><h3><p><span ng-bind="options"></span></p>';
return {
restrict: 'AE',
scope: {
model: "=",
options: "=?" //A JSON object
},
controller: function($scope) {
$scope.options = $scope.options || {};
//A function that sets default values if no options object passed
ensureDefaultOptions($scope);
//now based on some of the options passed in, I modify a property in the options object
if ($scope.options.isFlagOn)
$scope.options.thisProp = true;
},
link: function(scope, element, attr) {
let content = $compile(template)(scope);
element.append(content);
}
};
}
编辑:我解决了我的问题。我的解决方案发布在下面的答案中。
答案 0 :(得分:0)
您可以将其更改为单向绑定:
scope: {
model: "=",
options: "<?" //A JSON object
}
答案 1 :(得分:0)
您的指令应该复制传入的选项并结合默认值,因此每个指令实例都有自己的选项对象。
您可以使用extend
var defaultOptions = { a:1, b:2, c:3 };
var options = angular.extend(defaultOption, $scope.options);
// then use options everywhere
请注意,这只会在初始化期间执行一次,因此如果您的选项是异步来自控制器,则需要额外处理。
答案 2 :(得分:0)
我使用1.4x或更高版本中可用的Angular指令的bindToController属性解决了它。
angular.module('myModule', [])
.directive('myDirective', function($compile) {
template = '<h3><span ng-bind="vm.model.title"><h3><p><span ng-bind="myOptions"></span></p>';
return {
restrict: 'AE',
bindToController: {
model: "=",
options: "=?" //A JSON object
},
scope: {},
controller: function() {
var vm = this;
//a function that handles modifying options
vm.setOptions = function(options){
let newOptions = {};
angular.copy(options, newOptions);
// modify newOptions here
return newOptions;
}
},
controllerAs: 'vm',
link: function(scope, element, attr) {
ensureDefaultOptions(scope.vm);
scope.myOptions = scope.vm.setOptions(scope.vm.options);
let content = $compile(template)(scope);
element.append(content);
}
};
});