簡體   English   中英

具有雙向綁定和ng-change的AngularJS指令

[英]AngularJS directive with two-way binding and ng-change

我遇到了一種情況,我需要根據下拉菜單的選定值來更改輸入框的輸入類型。 換句話說,如果用戶從下拉列表中選擇“字符串”,則輸入的類型應該為“文本”,依此類推。我決定創建一個指令cuz,盡管我仍在學習Angular,但也不要復制塊到處都是代碼(我不止一次需要這樣做)。

這是我嘗試的內容:

(function () {
    "use strict";

    angular
        .module('app')
        .directive('dynamicTypeInput', dynamicTypeInput);

    function dynamicTypeInput() {
        return {
            replace: true,
            restrict: 'AE',
            require: ['ngModel', '^form'],
            scope: {type: '=', placeholder: '@'},
            templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html',
            link : function(scope, element, attrs, ngModel){

                //Watch for changes to ngModel, update scope.inputValue
                scope.$watch(function(){
                    return ngModel[0].$modelValue;
                }, function (value){
                    scope.inputValue = value;
                });

                //Watch inputValue, update the model
                scope.$watch('inputValue', function(value){
                    ngModel[0].$setViewValue(value);
                });

                //Setup ng-change
                if (attrs.ngChange) {
                    ngModel[0].$viewChangeListeners.push(function () {
                        scope.$eval(attrs.ngChange);
                    });
                }
            }
        };
    }
})();

注意:模板只是一個ng-switch ,它根據scope.type的值選擇適當的輸入框,並且所有輸入都綁定到scope.inputValue

我使用了這個 SO問題的答案來幫助我增加添加ng-change屬性並正確觸發的功能。 根據該答案,我需要從隔離范圍中刪除ngModel,我不確定為什么需要這樣做,但是,如果有人可以解釋它,我將不勝感激。

從隔離的作用域中刪除ngModel使得在初始控制器中更改模型時更難以實例化具有初始值的指令或更新指令,因此現在我觀察ngModel[0].$modelValue並在更改時更新本地值。

盡管該指令可以正常工作並且可以實現我期望的功能,但是看起來似乎有些復雜且效率低下,但是,我沒有辦法以更簡單的方式實現我想要的功能嗎?

使用所引用的SO問題的第二個答案 ,我解決了需要從隔離范圍中刪除ngModel以便使ngChange起作用的問題。 這簡化了指令,我可以按原樣使用雙向綁定。

最終指令:

(function () {
    "use strict";

    angular
        .module('app')
        .directive('dynamicTypeInput', dynamicTypeInput);

    dynamicTypeInput.$inject = ['$timeout'];

    function dynamicTypeInput($timeout) {
        return {
            replace: true,
            restrict: 'AE',
            require: ['ngModel', '^form'],
            scope: {ngModel: '=', type: '=', placeholder: '@', ngChange: "&"},
            templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html',
            link: function (scope, element, attrs, ngModel) {

                scope.$watch('ngModel', function () {
                    $timeout(scope.ngChange);
                });

            }
        };
    }
})();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM