Trancluded Directive和ngModelCtrl上的自定义属性

时间:2016-03-13 00:41:08

标签: javascript angularjs angularjs-directive angularjs-scope

我正在编写一个包含输入字段的指令,并在应用程序中添加了我想要的一些标准功能。我将输入元素转换为我的指令模板,以便在将其转换为包装器指令之前将ng-focus和其他属性添加到输入字段。现在,模板正确加载,但范围方法没有触发已注册的事件处理程序。到目前为止我的代码:

The Transcluded Directive

editInput.$inject = ['$parse'];
function transcludedDir($parse) {
    return {
        require: ['^wrapperDir', 'ngModel'],
        restrict: 'A',
        template: function(tElem, tAttrs) {
            tElem.attr('ng-key-enter', 'onInputSave()');
            return tElem;
        },
        link: function($scope, element, attrs, ctrls){
           ctrls[0].setNgModel(ctrls[1]);
            ctrls[0].modelSetter(function(value){
                $parse(atrs['ngModel'])($scope, value);
            });
            $scope.onInputSave = ctrls[0].save;
        }
    };
}

包装器指令(按下某些按钮,委派保存功能等)

   wrapperDir.$inject = ['$q'];
    function wrapperDir($q) {
        return {
            transclude: true,
            restrict: 'E',
            scope: {
                onSave: '&'
            },
            templateUrl: 'template.tpl.html',
            controller: function($scope){
                var modelCtrl;
                var initialValue;
                var updateValue;
                this.setNgModel = function(ngModel){
                    modelCtrl = ngModel;
                    initialValue = modelCtrl.$modelValue;
                };
                this.modelSetter = function(setterFunction){
                    updateValue = setterFunction;
                };
                this.save = $scope.save = function save(){
                    var currentValue = modelCtrl.$modelValue;
                    var result = $scope.onSave({
                        currentValue: currentValue,
                        initialValue: initialValue
                    });
                    $q.when(result).then(function(res) {
                        initialValue = currentValue;
                    });
                };
                return this;
            }
        };
    }

包装器目录模板和示例用法。 Wrapper Directive模板很简单,我只是用transcluded-dir来装饰输入,以确保翻译链接挂起特殊属性等。用法看起来像这样:

<!-- template.tpl.html -->
<div>
    <!-- Input is jammed in here via transclusion -->
    <div ng-transclude></div>
    <div><!-- actions i want to append (buttons, etc) --></div>
</div>

<!-- Sample usage -->
<wrapper-dir on-save="mySaveFn()">
    <input transcluded-dir type='text' ng-mode="my_little_teapot"
</wrapper-dir>

ng-key-enter对输入字段中的输入执行操作,但是转换范围中的onInputSave方法永远不会触发。有任何想法吗?如果你做到这一点,请提前致谢。

1 个答案:

答案 0 :(得分:0)

我找到了一个可接受的解决方法,它在转换控制器中使用以下语法:

editInput.$inject = ['$parse'];
function transcludedDir($parse) {
    return {
        require: ['^wrapperDir', 'ngModel'],
        restrict: 'A',
        link: function($scope, element, attrs, ctrls){
           ctrls[0].setNgModel(ctrls[1]);
           ctrls[0].modelSetter(function(value){
               $parse(atrs['ngModel'])($scope, value);
           });

           element.bind('keypress', function(event) {
               if (element.which == 13) {
                   ctrls[0].save(event);
               }
           )};
    };
}

我在链接函数期间添加ng-clickng-change作为属性并重新编译元素的成功有限,但在某些事件的模型上看到了奇怪的行为。通过标准的javascript事件,转换工作顺利进行。

// This worked for some directives, but was inconsistent
element.attr('ng-key-enter', clickToEdit.save);
element.removeAttr('transcluded-dir');
element.removeAttr('data-transcluded-dir');
$compile(element)($scope);