同一角度指令的多个实例混淆了范围变量
Multiple instance of same angular directive mess up scope variables
我像一样在页面上多次使用该指令
<div data-escape-amp-curation-multi-value-selector
data-binding-path="model"
data-search-key="journeys"
data-current-selection-model="model.journeys">
</div>
<div data-escape-amp-curation-multi-value-selector
data-binding-path="model"
data-search-key="targets"
data-current-selection-model="model.targets">
</div>
我的指令看起来像
var directive : ng.IDirective = {
restrict : 'A',
template : '<select multiple="multiple" data-options="sources/>',
compile() {
return {
pre(scope : any, element : any, attrs : any) {
scope.readonly = attrs.readonly === 'true';
},
post(scope : any, element : any, attrs : any) {
var binder = $parse(attrs.currentSelectionModel),
valueDropDown = element.find('select.value-dropdown'),
kendoMultiSelect = valueDropDown.data('kendoMultiSelect'),
defer = $q.defer();
/**
* The method to do search.
* @type {void}
*/
scope.doSearch = () = > {
scope.showSpinner = true;
scope.$evalAsync(() = > {
if (!cache) {
metadataService.getMetadata(attrs.searchKey).then(
result = > {
cache = result;
scope.sources = result;
defer.resolve();
},
error = > {
defer.reject(error);
});
} else {
scope.sources = cache;
defer.resolve();
}
defer.promise.then(() = > {
kendoMultiSelect.setDataSource(scope.sources);
scope.showSpinner = false;
kendoMultiSelect.value(binder(scope));
});
});
};
kendoMultiSelect.bind('change', () = > {
binder.bind(scope, kendoMultiSelect.value());
});
/**
* Set cache to null on location change
*/
scope.$on(LOCATION_CHANGE_START, () = > {
cache = null;
});
scope.$watch(() = > scope.$eval(attrs.currentSelectionModel), () = > {
if (!scope.sources) {
if (angular.isDefined(cache) && cache !== null) {
$timeout(() = > {
scope.sources = cache;
kendoMultiSelect.setDataSource(scope.sources);
kendoMultiSelect.value(binder(scope));
});
} else {
scope.doSearch();
}
} else {
kendoMultiSelect.setDataSource(scope.sources);
kendoMultiSelect.value(binder(scope));
}
});
}
}
}
}
当此代码呈现时,它会调用后端服务以根据搜索关键字填充源,但bot实例的scope.sources会获得相同的值。它获取上次搜索服务调用的值。我在这里缺少什么?谢谢
scope
在Angular中是原型继承的,但只有在您请求时才会创建新的作用域。在这种情况下,您只是在装饰由您的指令所在的父级定义的现有范围。
这意味着添加到作用域的任何内容都将被同一指令覆盖。
只需将scope:true
属性添加到指令定义对象中,就可以告诉指令创建一个新的作用域
{
restrict : 'A',
scope:true
//more stuff
}
下面是一个简单的示例,用于显示创建新作用域的指令和不创建的指令之间的区别。
(function() {
'use strict';
function NoNewScope() {
return {
restrict: 'A',
template: [
'<div class="form-group">',
' <label>Name - <code>{{name}}</code></label>',
' <input class="form-control" type="text" ng-model="name" />',
'</div>'
].join(''),
link: function(scope) {
scope.name = "No New Scope";
}
};
}
function NewScope() {
return {
restrict: 'A',
scope: true,
template: [
'<div class="form-group">',
' <label>Name - <code>{{name}}</code></label>',
' <input class="form-control" type="text" ng-model="name" />',
'</div>'
].join(''),
link: function(scope) {
scope.name = "New Scope";
}
};
}
angular.module('my-app', [])
.directive('noNewScope', NoNewScope)
.directive('newScope', NewScope);
}());
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="my-app" class="container">
<div class="row">
<div class="col-xs-6">
<h3>NO new scope</h3>
<div no-new-scope></div>
<div no-new-scope></div>
</div>
<div class="col-xs-6">
<h3>NEW scope</h3>
<div new-scope></div>
<div new-scope></div>
</div>
</div>
</div>
相关文章:
- 向模板实例变量传递调用方法调用的结果时出现异常
- Rails/Javascript:将实例变量传递给Coffeescript时发生Uncaught ReferenceEr
- 访问 javascript 对象的实例变量
- Angular2/Typescript:从链接可观察函数访问实例变量
- 如何在Promise回调中访问实例变量
- 如何使用每个ajax请求更新实例变量
- 实例变量变为未定义 - CoffeeScript
- 如何显式创建实例变量
- 如何在 JavaScript 中创建实例变量
- 模块化模式中的私有实例变量
- 将实例变量传递给 js Rails
- 找出实例变量名称本身
- 从视图中访问另一个操作实例变量
- 从视图访问实例变量
- 在主干模型中定义实例变量的正确方法是什么
- 是否可以在 javascript 中的私有函数中调用实例变量
- 将 rails 实例变量用于 javascript 条件
- 将实例变量替换为局部变量
- 为什么当我通过 Ajax 请求刷新部分时我的实例变量为空
- 实例变量