Angular指令修改ngModel的数据

时间:2014-10-21 13:42:54

标签: angularjs angularjs-directive

我为自定义下拉列表做了一个指令。一切都按预期工作 - 我在控制器中定义所有选项并将它们传递给指令。 Directive生成html,并在更改时将选定的值传递给我的ngModel。

我想改进的是。最初我只是将ngModel设置为PUBLICPRIVATEHIDDEN。然后指令(已经知道?)图标和要在下拉列表中显示的值。选择完成后,我的模型只会是PUBLICPRIVATEHIDDEN而不是{ name: 'Public', icon: 'globe', value: 'PUBLIC' }

指令:

.directive('sidPrivacyDropdown', function () {

    return {
        template:   '<div class="input-group sid-privacy-dropdown">\
                        <ui-select ng-model="selectedValue" theme="bootstrap" search-enabled="false" ng-disabled="disabled">\
                            <ui-select-match>{{selectedValue.name}}</ui-select-match>\
                            <ui-select-choices repeat="option in selectOptions">\
                                <div><span class="icon icon-{{option.icon}}"></span>{{option.name}}</div>\
                            </ui-select-choices>\
                        </ui-select>\
                    </div>',
        scope: {
            selectedValue: '=',
            selectOptions: '='
        },
        replace: true
    };
});

控制器:

$scope.privacyOptions = [
    { name: 'Public',   icon: 'globe',  value: 'PUBLIC'     },
    { name: 'Members',  icon: 'group',  value: 'MEMBERS'    },
    { name: 'Hidden',   icon: 'lock',   value: 'HIDDEN'     }
];

HTML:

<div sid-privacy-dropdown selected-value="edit.privacy.field" select-options="privacyOptions"></div>

由于我对Angular和指令相对较新,我不知道应该如何或在哪里修改值。最终我希望ngModel只是一个常量。

I also prepared a Plunker

编辑!也许这有助于更好地理解我想要的内容:

这是一个Plunker,可以完成我想要它做的一半:Plunker。我现在可以将'HIDDEN'指定为初始值。该指令从所有选项中获取正确的项目并显示它。我不能让它以相反的方式工作。当'selectedObject'发生变化时,它应该更新selectedValue

1 个答案:

答案 0 :(得分:0)

我使用$watch找到了一个有效的解决方案。反馈会有所帮助。因为$watch似乎有点像作弊,让我觉得有更好的解决方案。

无论如何,我不得不改变我的指示。

app.directive('sidPrivacyDropdown', function () {

    return {
        template:   '<div class="input-group sid-privacy-dropdown">\
                        <ui-select ng-model="$parent.selectedObject" theme="bootstrap" search-enabled="false" ng-disabled="disabled">\
                            <ui-select-match>{{selectedObject.name}}</ui-select-match>\
                            <ui-select-choices repeat="option in selectOptions">\
                                <div><span class="glyphicon glyphicon-{{option.icon}}"></span>{{option.name}}</div>\
                            </ui-select-choices>\
                        </ui-select>\
                    </div>',
        scope: {
            selectedValue: '=',
            selectOptions: '='
        },
        link: function(scope, elem, attrs) {
            scope.$watch('selectedObject', function(obj){
                scope.selectedValue = obj['value'];
            });
            scope.selectedObject = angular.copy(scope.selectOptions.filter(function(obj){return obj['value'] === scope.selectedValue})[0]);
        },
        replace: true
    };
});

首先,我找到selectedObject的相应隐私对象,并在模板中使用它。现在当ui-select更新selectedObject时,我使用$watch来捕获它并将selectedValue设置为selectedObject['value']

这样做可以达到我想要的效果,但我认为这可以在没有$watch的情况下完成?