我在页面上多次使用该指令,如
<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获取相同的值。 它获取上次搜索服务调用的值。 我在这里缺少什么? 感谢。
答案 0 :(得分:1)
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>