我正在尝试创建一个允许我绑定到其他范围属性的哈希的指令。
<div lookup lookup-model="data.countryId"></div>
<div lookup lookup-model="data.stateId" lookup-params="{countryId: data.countryId}"></div>
我希望能够每次更新lookup-params中的值以使用data.stateId模型刷新查找。我试图保持这种通用性,因为我可能会有各种不同的查找参数。
有没有办法在Angular中执行此操作?
我当然没有提供足够的细节。点击过早提交。这是我的解决方案,基于@Olivvv的反馈。该建议引导我进入scope.$eval
功能。
这里的目标是创建一个指令,允许我们使用带有$http
的select来选择select中的选项。一些$http
请求将需要一个参数,因为它们是对另一个值的依赖。例如,只有在提供国家/地区值时才能提供一组状态。
以下是我汇总的代码。我确信它可以改进,但它现在正在做的伎俩。请注意,我正在使用Lodash实现一些实用功能。您还将看到范围对象“lookupModelObject”。这纯粹是为了满足造型选择的设计需求。如果您只对lookupParams
感兴趣,可能会被忽略。
<div select-lookup lookup-value="block.data.countryId" lookup-type="countries" lookup-placeholder="Select a Country"></div>
<div select-lookup lookup-value="block.data.stateId" lookup-type="states" lookup-params="{countryId: block.data.countryId}" lookup-placeholder="Select a State"></div>
要指出的重要部分是我如何评估attrs.lookupParams
。如果属性存在,我使用scope.$eval
来评估属性。稍后您将看到我如何将每个参数添加到范围中,并在其中一个参数更改时添加了一个观察程序。如果选择了其他国家/地区,这将允许我将“state”重置为null。
angular.module("foo").directive('selectLookup', ['$http', '$q', function($http, $q) {
return {
restrict: 'A',
replace: true,
templateUrl: 'common/lookups/partials/selectLookupPartial.html',
scope: {
id: "@",
lookupValue: "=",
lookupParams: "="
},
link: function(scope, element, attrs) {
// Initialize the options.
scope.options = [];
var optionsLoaded = false;
var resetLookupModel = function() {
scope.lookupModelObject = {
id: null,
text: attrs.lookupPlaceholder
};
};
// Evaluate and obtain the lookup parameters for this lookup.
var lookupParams = {};
if (attrs.lookupParams) {
lookupParams = scope.$eval(attrs.lookupParams);
}
var updateLookupModelObject = function(value) {
// This function is only relevant if the options have been loaded.
if (optionsLoaded) {
if (value === undefined || value === null) {
resetLookupModel();
}
else {
var item = _.findWhere(scope.options, {id: value});
if (item) {
scope.lookupModelObject = item;
}
else {
resetLookupModel();
}
}
}
};
var fetchValues = _.throttle(function() {
var deferred = $q.defer(),
fetchUrl = "/api/lookup/" + attrs.lookupType,
keys = _.keys(lookupParams);
_.each(keys, function(key, index) {
if (index === 0) {
fetchUrl += "?";
}
else {
fetchUrl += "&";
}
fetchUrl += key + "=" + lookupParams[key];
});
// Empty the options.
scope.options.splice(0, scope.options.length);
$http.get(fetchUrl).then(function(response) {
scope.options = response.data;
optionsLoaded = true;
updateLookupModelObject(scope.lookupValue);
deferred.resolve(scope.options);
});
return deferred.promise;
}, 150);
// Setup the watchers
// If there are lookup params add them to scope so we can watch them.
var keys = _.keys(lookupParams);
_.each(keys, function(key) {
scope[key] = lookupParams[key];
// Setup watchers for each param.
scope.$watch(key, function() {
fetchValues();
});
});
scope.$watch('lookupParams', function(newValue, oldValue) {
if (!_.isEqual(newValue, oldValue)) {
lookupParams = newValue;
fetchValues().then(resetLookupModel);
}
});
scope.$watch('lookupValue', updateLookupModelObject);
scope.$watch('lookupModelObject', function(newValue, oldValue) {
if (!_.isEqual(newValue, oldValue)) {
scope.lookupValue = newValue.id;
}
});
fetchValues();
}
};
}]);
我们有一个设计约束,迫使我们引入一个“选择占位符”。除此之外,select是在Angular中设置选择的“典型”方式。
<div class="container select-container">
<div class="select-placeholder">
<span class="select-placeholder-text">{{ lookupModelObject.text }}</span>
<select class="select-input" data-ng-model="lookupModelObject" id="{{ id }}" data-ng-options="option as option.text for option in options"></select>
</div>
</div>
答案 0 :(得分:0)
我在&#34; utils&#34;中使用以下函数解决了它。服务:
function utils ($parse) {
this.$params = function(attrs, attrName, allowedParams){
var out = {},
parsed = $parse(attrs[attrName])();
if (typeof parsed === 'object'){
angular.forEach(parsed, function(val, key){
if (allowedParams.indexOf(key) !== -1){
this[key] = val;
} else {
//do some logging. i.e ('parameter not recognized :', key, ' list of the allowed params:', allowedParams)
}
}, out);
}else{
out[allowedParams[0]] = attrs[attrName];
}
return out;
};
}
在模板中使用它:
lookup-params="{countryId: '{{data.countryId}}'}"
并在你的指令中:
var lookupParams = utils.$params(attrs, 'lookup-params', ['countryId','anotherParams', 'etcetera']);
第一个允许的参数可以直接作为字符串而不是对象传递:
lookup-params="{'{{data.countryId}}'}"
将起作用