AngularJS:双向绑定指令中的未知属性

时间:2015-06-25 15:41:29

标签: javascript angularjs angularjs-directive

我已经构建了一个基本上创建友情下降的文本编辑器的指令。它将在我的网站的各个地方使用,最终用户想要使用markdown来做一些基本的内容样式(产品描述,那种事情)。挑战在于,由于该指令将部署在多个地方,因此不会在每个模型上编辑相同的属性。例如,在一个位置它可以编辑产品的LongDescription,而在另一个位置它可以编辑广告活动的ShortDescription或用户的Bio。

我需要能够使用范围' ='将要编辑的属性传递给指令。允许双向数据绑定的方法,因此在指令和原始控制器上都更改了属性,允许用户保存这些更改。我遇到的问题是,如果我将属性本身传递给指令:

<markdown-editor model="product.Description"></markdown-editor>

双向数据绑定不起作用,因为它传递了Description属性的值。我知道对于&#39; =&#39;在指令中进行双向绑定的方法,我必须从HTML中传递一个对象作为属性值。我可以轻松传递整个对象:

<markdown-editor model="product"></markdown-editor>

然后访问指令中的Description属性:

<textarea ng-model="model.Description"></textarea>

但是这个硬编码描述到指令中,我可能并不总是想要那个属性。

所以我的问题是,我怎么能双向绑定到我的对象的单个属性,而没有指令提前知道该属性是什么?我提出了一个解决方法,但它非常难看:

HTML:

<markdown-editor model="contest" property="Description"></markdown-editor>

指令JS:

angular.module('admin.directives').directive('markdownEditor', [
    'admin.constants.templateConstants',
    '$sce',
    function (Templates, $sce) {
        var directive = {
            restrict: 'E',
            replace: true,
            templateUrl: Templates.Directives.MarkdownEditor,
            scope: {
                model: '=',
                property: '@'
            },
            controllerAs: 'markdownEditor',
            controller: markdownEditorController
        }

        function markdownEditorController($scope) {
            var vm = this;
            vm.display = { markdown: true };
            vm.content = { markdown: '', html: '' }; 

            console.log($scope.model);

            vm.setDisplay = function (type) {
                vm.display = {};
                vm.display[type] = true;
            }

            $scope.$watch('model', function (newModel, oldModel, $scope) {
                vm.content.markdown = $scope.model[$scope.property];
            });

            $scope.$watch('markdownEditor.content.markdown', function (newDescription, oldDescription, $scope) {
                $scope.model[$scope.property] = newDescription;
                if (newDescription !== "" && newDescription !== null && newDescription !== undefined) {
                    vm.content.html = $sce.trustAsHtml(marked(newDescription));
                }
            });
        }

        return directive;
    }
]);

指令模板的相关部分:

<textarea class="ad-basic-input" ng-model="markdownEditor.content.markdown" ng-if="markdownEditor.display.markdown"></textarea>

请注意,该指令使用watch来查找content.markdown字段的更改,然后手动将它们推回到model [property]中(底部附近的第二个$ watch)。它还必须监视从上面的控制器传入的模型的更改,因为它是异步加载的,并且最初需要分配到content.markdown字段。

这段代码很有效,但是这两款手表,尤其是那款寻找模特变化的手表,对我来说似乎是一个很大的代码味道。当该属性未知时,肯定有更好的方法来传递,编辑和双向绑定控制器上对象的单个属性?

谢谢!

0 个答案:

没有答案