HTML
Filter:
<input type="radio" ng-model="Type" value="Rear"> Rear
<input type="radio" ng-model="Type" value="Front"> Front
<br>
Select:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
指令:
.directive('nameValueSelect', function () {
return {
restrict: "E",
scope: {
entry: "=",
field: "@",
options: "=",
onInputChange: "&"
},
controller: function ($scope) {
$scope.onChange = function () {
console.log("selected changed");
$scope.entry.type = $scope.option.value;
$scope.onInputChange();
};
var getItemForValue = function (value) {
var item = null;
$scope.options.forEach(function (_option) {
if (_option.value == value) {
item = _option;
}
});
return item;
};
$scope.$watch("entry", function () {
console.log("entry changed");
$scope.option = getItemForValue($scope.entry[$scope.field]);
}, true);
},
template: '<select ng-model="option" ng-options="o.Description for o in options" ng-change="onChange()"><option value="" selected="selected">Please Select </option></select>'
}; })
控制器:
$scope.Description = '';
$scope.entry = {Description: ''};
$scope.Type = 'Front';
$scope.entry.type = '';
$scope.$watch('Type', function (Type) {
$scope.filterTypes = [];
$scope.axleTypes = new API.GetAxleTypes(function () {
angular.forEach($scope.axleTypes, function(axleType) {
if (axleType.Type == Type) {
this.push(axleType);
}
// if(!$scope.$$phase) $scope.$digest(); // tried this, does not have any affect
}, $scope.filterTypes); // '}, $scope.filterTypes, true)'--> did nothing for me here
});
$scope.filterTypes.sort(function (a, b) {
return a.Description.localeCompare(b.Description);
});
}); // '}, true)' --> did nothing for me here
问题:
自定义选择控件最初会填充“Front”类型的项目,如果我将Rear设置为默认值,也会填充“Rear”。
但是,在单选按钮之间切换时,不会调用监视功能,并且选择不会填充符合新选择的过滤器类型的项目。
/////////////////////////////////////////////// /////// 缩小问题: ////////////////////////////////////////////////// ///
当把它移到一个独立的项目时,我发现上面的代码有效: - (
以下是原始选择NOT作为自定义指令:
<select ng-model="$parent.selectedFrontAxle" ng-options="axleType.Description for axleType in axleTypes | filterByType: 'Front' | orderBy:'Description'" id="frontAxles" class="formRequire" required>
<option value="" selected>Select Axle Type ..</option>
</select>
以下是选择控件作为自定义指令:
<name-value-select entry="entry" field="axleType" options="filterTypes"></name-value-select>
显然这就是问题所在:“ng-model =”$ parent.selectedFrontAxle“
如果我采用指令“name-value-select”并将其移动到父页面,代替include语句,它可以工作。
但这不是我想要的。所以我需要将它留在包含页面中。
然而,如果我采用 ng-model =“$ parent.selectedFrontAxle”并将其添加到包含页面上的任何元素,则无效。
任何没有 ng-model =“$ parent.selectedFrontAxle”的人,仍然无效。
我可以看到问题是范围但我没有看到如何纠正它。
Ughh !!!仍然没有解决方案。
//
//
////////////////////////////////////////////////// ////////////
Mark Rajcok
////////////////////////////////////////////////// ////////////
一如既往地感谢您的帮助。虽然,我不认为我在第2点说得很清楚,当时我说我有想要代码预过滤而不是用户的场景。我想通了。因此,对于任何希望通过指令抽象出控件的人来说,并且,就像在这种情况下,用户和代码执行过滤过程的地方一样,这里是plunker解决方案:
答案 0 :(得分:4)
在this plunker中,我重新编写代码以允许用户选择“Rear”或“Front”,并且选择列表将动态更新。所选值在MainCtrl范围内以$scope.selected.item
形式提供。 (我删除的指令中有很多不必要的代码。使用ng-model时不需要onChange处理程序。)
<name-value-select selected-item="selected.item" options="filterTypes">
</name-value-select>
app.directive('nameValueSelect', function () {
return {
restrict: "E",
scope: {
selectedItem: "=",
options: '='
},
template: ...
由于ng-include创建子范围,所有原始属性都转换为对象属性,因此JavaScript原型继承将按预期工作(即,当值更改时,MainCtrl中定义的$ scope对象将更改而不是新的在本地范围内创建原始属性。)
我相信上面提到的那个傻瓜会满足你的“第一点”。
我现在将看看为“第2点”创建一个plunker ...(我在更新此答案时会添加评论)。
This plunker过滤指令中的选择列表:
<name-value-select selected-item="selected.item" choice="choice.type"
options="myTypes"></name-value-select>
app.directive('nameValueSelect', function () {
return {
restrict: "E",
scope: {
selectedItem: "=",
choice: "=",
options: "=",
},
controller: function($scope) {
$scope.$watch('choice', function (selectedType) {
$scope.selectedItem = ''; // clear selection
$scope.filterTypes = [];
angular.forEach($scope.options, function (type) {
if (type.Type === selectedType) {
this.push(type);
}
}, $scope.filterTypes);
$scope.filterTypes.sort(function (a, b) {
return a.Description.localeCompare(b.Description);
});
});
},
template: '<select ng-model="selectedItem" ' +
'ng-options="o.Description for o in filterTypes">' +
'<option value="" selected="selected">Please Select</option>' +
'</select>'
};
});
答案 1 :(得分:-1)
我并不完全理解您的请求,但我只是假设您要根据单选按钮组的值动态更改选择的内容。选择被过滤和排序,您可以选择要显示的数据字段。
您可以查看此Plunker,其中包含一些经过修改的演示。
<强> HTML 强>
Filter:
<input type="radio" ng-model="filter.type" value="rear"> Rear
<input type="radio" ng-model="filter.type" value="front"> Front
<br />
Field:
<select ng-model="filter.field" ng-options="item for item in fields"></select>
<br />
Select:
<select ng-model="entry" ng-options="item[filter.field] for item in entries | filter:type=filter.type | orderBy:filter.field">
<option value="">Default</option>
</select>
<br />
Selected: <span>{{entry}}</span>
<h2>Alternative</h2>
Filter: <span>{{filter}}</span>
<br />
<select ng-model="altentry" ng-options="item[filter.field] for item in altentries | orderBy:filter.field">
<option value="">Default</option>
</select>
<br />
Selected: <span>{{altentry}}</span>
<强> JS 强>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
/* Default filter values */
$scope.filter = {
type: 'rear',
field: 'name'
};
/* List of fields */
$scope.fields = [
"id", "type", "name"
];
/* Data coming from an API */
$scope.entries = [
{"id":1, "type":"rear", "name":"Rear Part 01"},
{"id":2, "type":"rear", "name":"Rear Part 03"},
{"id":3, "type":"rear", "name":"Rear Part 05"},
{"id":4, "type":"rear", "name":"Rear Part 02"},
{"id":5, "type":"rear", "name":"Rear Part 04"},
{"id":6, "type":"front", "name":"Front Part 01"},
{"id":7, "type":"front", "name":"Front Part 03"},
{"id":8, "type":"front", "name":"Front Part 05"},
{"id":9, "type":"front", "name":"Front Part 02"},
{"id":10, "type":"front", "name":"Front Part 04"},
];
/* Simulate different ajax return */
$scope.$watch('filter.type', function(newval, oldval) {
if (newval || newval !== oldval) {
$scope.altentries = [];
angular.forEach($scope.entries, function(v,k) {
if (v.type === $scope.filter.type) {
$scope.altentries.push(v);
}
});
}
});
/* Monitoring any selected value */
$scope.$watch('entry', function(newval, oldval) {
console.log('entry:', oldval, newval);
}, true);
$scope.$watch('altentry', function(newval, oldval) {
console.log('altentry:', oldval, newval);
}, true);
});