angularjs 将 ngModel 从包装器指令传递到包装器指令

2024-05-13

我是 Angular 的新手,但仍然痛苦地纠结于自定义指令。

我想重用这段 HTML

<ui-select ng-model="model.selectedLanguages" multiple search-enabled="true" theme="select2" style="width: 300px;">
    <ui-select-match placeholder="Pick one...">{{$item.name}}</ui-select-match>
    <ui-select-choices repeat="lang.id as lang in langs |filter: { name : $select.search }">
        <div ng-bind-html="lang.name | highlight: $select.search" ></div> 
    </ui-select-choices>
</ui-select>

通过将其包装到我的自定义指令中:

<language-picker ng-model="model.selectedLanguages"/>

像这样的东西:

app.directive('languagePicker', function() {
            return {
                template : '<ui-select ng-model="**PARENT'S NGMODEL**" multiple search-enabled="true" theme="select2" style="width: 300px;"><ui-select-match >{{$item.name}}</ui-select-match><ui-select-choices repeat="lang.id as lang in langs | filter: { name : $select.search }"><div ng-bind-html="lang.name | highlight: $select.search"></div></ui-select-choices></ui-select>',
                restrict : 'E',
                require : 'ngModel',
                replace : true
                    ....
            };
        });

但是我如何从我的language-picker to the ui-select指令?

UPDATE

使用下面的建议,我让它与 ui-select 一起工作,但外部模型根本没有更新,请参阅plnkr.co/edit/Y43dmMGIc5GxM9fLoNPW http://plnkr.co/edit/Y43dmMGIc5GxM9fLoNPW,可能是因为它的子作用域和父作用域保持不变?

UPDATE 2

我让它以一种复杂的方式工作,这对我来说看起来很可怕,因为我不知道为什么它首先“工作”(看看控制器中发生的奇怪的事情):

app.directive('languagePicker', function(LanguageService) {
            return {
                templateUrl : 'LanguagePickerTpl.html',
                restrict : 'E',
                scope : {
                    languages : '='
                }, 
                controller : function($scope, LanguageService) {
                    console.log($scope);
                    $scope.langs = LanguageService.get();
                    $scope.model = $scope;
                }

            };
        })

模板:

<ui-select ng-model="model.languages" multiple search-enabled="true" 
  theme="select2" style="width: 300px;">
    <ui-select-match>{{$item.name}}</ui-select-match>
    <ui-select-choices repeat="lang.id as lang in langs | filter: { name : $select.search }">
      <div ng-bind-html="lang.name | highlight: $select.search"></div>
    </ui-select-choices>
  </ui-select>

如果有人能解释发生了什么,我会非常高兴(“工作”示例在这里http://plnkr.co/edit/B53F9sc7UGkj0uxUpC17 http://plnkr.co/edit/B53F9sc7UGkj0uxUpC17 )


The ng-model有一些特殊处理,请参阅here https://code.angularjs.org/1.3.15/docs/api/ng/type/ngModel.NgModelController在“自定义控件示例”标题下。步骤是:

  1. 我建议你使用隔离范围;它使组件的接口更加清晰,并避免副作用。在这种情况下,您想要传递可用选项(语言)的列表:

    scope: {
        langs: '='
    }
    

    用法是:

    <language-picker ng-model="model.selectedLanguages" langs="langs"/>
    
  2. 您的指令要求(也许可选)ngModel:

    require: ['ngModel']
    
  3. 你覆盖ngModel's $render方法,例如:

    link: function(scope,elem,attrs,ctrls) {
        var ngModelCtrl = ctrls[0];
        ngModelCtrl.$render = function() {
            ...
        };
    }
    

    渲染逻辑负责传输模型值(这里的值:<language-picker ng-model="model.selectedLanguages"/>, i.e. model.selectedLanguages)到视图。我能想到的最简单的事情就是使用隔离范围 and 将外部模型值传输到隔离范围的变量 as:

        ngModelCtrl.$render = function() {
            scope.innerSelection = ngModelCtrl.$viewValue;
        };
    

    在模板中将此变量绑定为:

    <ui-select ng-model="innerSelection" ...>
        ...
    </ui-select>
    
  4. 最后,您必须确保对内部选择的更改将传播到外部模型:

        // still inside link()
        scope.$watch('innerSelection', function(newval, oldval) {
            if( newval != oldval ) { // skip the first time
                ngModelCtrl.$setViewValue(newval);
            }
        });
    

该解决方案可能比其他解决方案复杂一些,但可以让您使用该解决方案的所有功能ngModel,例如验证、解析/格式化(即数据转换)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

angularjs 将 ngModel 从包装器指令传递到包装器指令 的相关文章

随机推荐