在md-select下使用自定义指令传递ngModel和ngChange

时间:2019-02-12 12:05:16

标签: javascript angularjs angularjs-material md-select

我在md-select上做了一个自定义指令。我遇到默认行为ngModelngChange的问题。我似乎无法让他们俩一起工作。

当前我有这个 http://next.plnkr.co/edit/X34DUWtkyYhbwJP4?open=lib%2Fscript.js

ngModel正在更新,但是ngChange似乎不起作用。

我也尝试过一种http://embed.plnkr.co/HZAHSyi9L8UQdE24zYYI/中显示的方法 但是在设置超时值时会遇到问题(假设值来自api)。

app.controller("appCtrl", function($scope){
  $scope.items = [1,2,3,4,5,6];
  $scope.foo=2; // this works
  $scope.bar = function(foo)  {
    $scope.aux = foo;
  }
  setTimeout(function(){
    $scope.foo=5;
  }, 0); // this doesnt work
});

我想使这两个属性像默认md-select一样起作用。

1 个答案:

答案 0 :(得分:1)

使用ng-model和自定义指令时,可以将ngModel指定为要求,然后自动访问其他指令,例如ngChangengRequired。我已更新您的plunkr:http://next.plnkr.co/edit/VzYpZ2elmzV6XkbM?open=lib

HTML

<md-custom-select 
    ng-model="vm.SelectItems" 
    ng-change="vm.onselectchange()" 
    list="vm.ItemList">
</md-custom-selector>

JavaScript

var app = angular.module("MaterialApp", ["ngMaterial"]);
app.directive("mdCustomSelect", ["$compile", mdCustomSelect]);

function mdCustomSelect($compile) {
    return {
        restrict: "E",
        require: {
            ngModelCtrl: '^ngModel'
        },
        scope: {
            ngModel: "<",
            list: "=",
            options: "<",
        },
        replace: true,
        link: function(scope, element, attrs, controllers) {
            scope.ngModelCtrl = controllers.ngModelCtrl;

            var searchTemplate = '<md-select-header aria-label="Select Header" class="demo-select-header"><input aria-label="InputSearchBox" ng-keydown="$event.stopPropagation()" ng-model="searchTerm" type="search" placeholder="Search items" class="md-text"></md-select-header>';
            var selectAllTemplate = '<div style="padding: 0px 0px 15px 5px; background-color: #efefef;"><md-checkbox class="md-warn" title="Select All" ng-model="checkAllChecked" ng-change="toggleSelectAll()">Check/Uncheck All </md-checkbox></div>';
            var multiSelectGroupTemplate = '<md-option ng-value="item.ItemID" ng-repeat="item in ItemList | filter: searchTerm">{{item.ItemName}}</md-option>';
            var completeTemplate = "";
            completeTemplate += '<md-select multiple ng-model="ngModel" ng-change="valChanged()" data-md-container-class="selectdemoSelectHeader">';
            completeTemplate += searchTemplate; //2 begin and end
            completeTemplate += selectAllTemplate; //3 begin and end
            completeTemplate += multiSelectGroupTemplate; //4 begin and end
            completeTemplate += " </md-select>"; //1 end
            element.html(completeTemplate);
            $compile(element.contents())(scope);
        },
        controller: ["$scope", function($scope) {
            var defaultValueProperty = ($scope.options == undefined || $scope.options.Value === undefined) ? "value" : $scope.options.Value;
            var defaultTextProperty = ($scope.options == undefined || $scope.options.Text === undefined) ? "name" : $scope.options.Text;
            $scope.isMultipleSelected = angular.isUndefined($scope.multiple) ? true : $scope.multiple;
            $scope.checkAllChecked = false;

            $scope.ItemList = [];
            var rawItemList;

            $scope.$watch("list", function(newValue) {
                $scope.ItemList = newValue.map(item => {
                    return { ItemID: item[defaultValueProperty], ItemName: item[defaultTextProperty] };
                });
            }, true);

            $scope.valChanged = function(){
                $scope.ngModelCtrl.$setViewValue($scope.ngModel);
            }

            $scope.toggleSelectAll = function() {
                if ($scope.checkAllChecked == false) {
                    $scope.ngModelCtrl.$setViewValue([]);
                } else {
                    $scope.ngModelCtrl.$setViewValue($scope.ItemList.map(item => item.ItemID));
                }
            };
        }]
    };
}