AngularJS 下拉指令通过双向绑定设置选中项
AngularJS Dropdown Directive Set Selected Item Through Two Way Binding
我有一个 angularjs 下拉指令。我希望能够将要选择的项目的 ID 作为指令的属性传递。像这样:
<dropdown selected-item-id="ctrl.selectedItemId"></dropdown>
我实现了这个,但没有用。如果我在指令代码中显示 itemId 的值,我可以看到正确的值,但下拉选择不会更新。这是相关代码:
(function () {
'use strict';
var dropdown = function ($state, service) {
return {
restrict: 'E',
replace: true,
templateUrl: '/dropdown.html',
scope: {
selectedItemId:"="
},
link: function (scope, elem, attr) {
service
.getItems()
.then(function (items) {
scope.items = items;
});
}
};
};
dropdown.$inject = ['$state', 'service'];
angular.module('app').directive('dropdown', dropdown);
})();
<select class="form-control"
ng-model="selectedItemId"
ng-options="item.id as item.name for item in items">
<option value="" selected disabled>Select an item</option>
</select>
就像我说的,如果我在指令模板上显示 selectedItemId(例如作为选项之一),我会看到正确的 id 值,但是下拉选择不会改变。
有什么想法吗?
编辑:
我在下拉菜单的 属性、item-id 到 selected-item-id
上有一个错字(在输入代码时发生,我的编辑器上的实际代码是正确的)
根据您的 html 代码,您没有按照您的想法将所选值绑定到商品 ID。您正在将所选值绑定到 selected-item-id。
尝试将您的 html 更改为:
<dropdown selected-item-id="ctrl.selectedItemId"></dropdown>
我不确定为什么它不像我原来那样工作,但我做了一些更改,现在它可以正常工作了。这是我所做的 (解释作为对源代码的注释包含在内):
//Here I use the selectedItem bidirectional binding on the .then of my service call
//to get the id of the items that's supposed to be selected.
//Then, I filter the array of items using that id, so I get the actual object that matches the id.
//Finally, I set the scope object "selectedItem" to that object I just got.
//The "selectedItem" object is what's bound to the select via ng-model so that does the selection.
(function () {
'use strict';
var dropdown = function ($state, service) {
return {
restrict: 'E',
replace: true,
templateUrl: '/dropdown.html',
scope: {
selectedItemId:"="
},
link: function (scope, elem, attr) {
service
.getItems()
.then(function (items) {
scope.items = items;
var selectedItem = $filter('filter')(items, { id: scope.selectedItemId })[0];
scope.selectedItem = selectedItem;
});
}
};
};
dropdown.$inject = ['$state', 'service'];
angular.module('app').directive('dropdown', dropdown);
})();
<!--Here I replaced the ng-model to use an object rather than an id and did the same on the ng-options -->
<select class="form-control"
ng-model="selectedItem"
ng-options="item as item.name for item in items">
<option value="" selected disabled>Select an item</option>
</select>
看起来您可能在 $digest 周期中遇到了竞争条件。如果您在代码的第一个版本上从服务回调中调用 $apply() 它应该可以工作。但是,您会不时遇到副作用,angular 会抱怨 $apply 已经在进行中,因此您的代码的第二个版本应该可以解决问题。
我有一个 angularjs 下拉指令。我希望能够将要选择的项目的 ID 作为指令的属性传递。像这样:
<dropdown selected-item-id="ctrl.selectedItemId"></dropdown>
我实现了这个,但没有用。如果我在指令代码中显示 itemId 的值,我可以看到正确的值,但下拉选择不会更新。这是相关代码:
(function () {
'use strict';
var dropdown = function ($state, service) {
return {
restrict: 'E',
replace: true,
templateUrl: '/dropdown.html',
scope: {
selectedItemId:"="
},
link: function (scope, elem, attr) {
service
.getItems()
.then(function (items) {
scope.items = items;
});
}
};
};
dropdown.$inject = ['$state', 'service'];
angular.module('app').directive('dropdown', dropdown);
})();
<select class="form-control"
ng-model="selectedItemId"
ng-options="item.id as item.name for item in items">
<option value="" selected disabled>Select an item</option>
</select>
就像我说的,如果我在指令模板上显示 selectedItemId(例如作为选项之一),我会看到正确的 id 值,但是下拉选择不会改变。
有什么想法吗?
编辑: 我在下拉菜单的 属性、item-id 到 selected-item-id
上有一个错字(在输入代码时发生,我的编辑器上的实际代码是正确的)根据您的 html 代码,您没有按照您的想法将所选值绑定到商品 ID。您正在将所选值绑定到 selected-item-id。
尝试将您的 html 更改为:
<dropdown selected-item-id="ctrl.selectedItemId"></dropdown>
我不确定为什么它不像我原来那样工作,但我做了一些更改,现在它可以正常工作了。这是我所做的 (解释作为对源代码的注释包含在内):
//Here I use the selectedItem bidirectional binding on the .then of my service call
//to get the id of the items that's supposed to be selected.
//Then, I filter the array of items using that id, so I get the actual object that matches the id.
//Finally, I set the scope object "selectedItem" to that object I just got.
//The "selectedItem" object is what's bound to the select via ng-model so that does the selection.
(function () {
'use strict';
var dropdown = function ($state, service) {
return {
restrict: 'E',
replace: true,
templateUrl: '/dropdown.html',
scope: {
selectedItemId:"="
},
link: function (scope, elem, attr) {
service
.getItems()
.then(function (items) {
scope.items = items;
var selectedItem = $filter('filter')(items, { id: scope.selectedItemId })[0];
scope.selectedItem = selectedItem;
});
}
};
};
dropdown.$inject = ['$state', 'service'];
angular.module('app').directive('dropdown', dropdown);
})();
<!--Here I replaced the ng-model to use an object rather than an id and did the same on the ng-options -->
<select class="form-control"
ng-model="selectedItem"
ng-options="item as item.name for item in items">
<option value="" selected disabled>Select an item</option>
</select>
看起来您可能在 $digest 周期中遇到了竞争条件。如果您在代码的第一个版本上从服务回调中调用 $apply() 它应该可以工作。但是,您会不时遇到副作用,angular 会抱怨 $apply 已经在进行中,因此您的代码的第二个版本应该可以解决问题。