Angular JS - 来自自定义指令的双向绑定

时间:2013-02-23 00:34:59

标签: data-binding angularjs directive dynamic-properties

如果这个问题已经得到解答,请指出我当前的位置(我搜索了很多但找不到匹配的解决方案 - 如果我错过了,我很抱歉!)

首先:目前我必须坚持使用AngularJS 1.0.0rc10 并且:(如果可能的话)我喜欢定义/调用指令保持这种方式的方式(因为它已经被非常广泛地使用)

这实际上应该是非常微不足道的 - 仍然,我不知道我的方法中的缺陷是什么。 基本上我已经创建了一些用于生成表单元素的自定义指令(它们比我提供的示例更复杂,但问题是相同的)。 我生成(实际上是我复制)控制器中的一个对象,将其传递到范围并使用我的指令绑定到该对象的各种属性(在示例中我添加了两个用例:单个列表和一个数组由转发器处理的对象)

当涉及到原始数据类型时,双向绑定似乎并不成功。 期望的结果应该是:更改纯文本属性的输入(它与instance-object一起使用)并在控制台中记录范围的对象(firefox:console.log),这应反映更改。

请注意我确实选择了编译方法,因为属性的名称(在本例中为:text和instance)应该在HTML视图中自由定义(=指令declerations)

我创造了一个小提琴: http://jsfiddle.net/matthias000/vqwHM/2/

如果小提琴不起作用,则代码为:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link href="bootstrap/css/bootstrap.css" rel="stylesheet">
    <link href="bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
    <script language="javascript" type="text/javascript" src="jquery/jquery-1.7.2.min.js"></script>
    <script language="javascript" type="text/javascript" src="angular/angular-1.0.0rc10.js"></script>
    <script language="javascript" type="text/javascript" src="bootstrap/js/bootstrap.js"></script>  
    <script type="text/javascript">
        angular.module('TestApplication', [])
            .directive('formTextInput', function() {
                return {
                    restrict: 'E',
                    compile: function(element, attrs) {
                        var htmlText = '<input class="input-small" type="text" ng-model="' + attrs.property + '">';
                        element.replaceWith(htmlText);
                    }
                }
            })
            .directive('formObjectInput', function() {
                return {
                    restrict: 'E',
                    compile: function(element, attrs) {
                        var htmlText = '<div class="input-append">' +
                            '<input class="input-small" type="text" ng-model="' + attrs.property + '.text">' +
                            '<span class="add-on">{{notimportant}}</span>' +
                        '</div>';
                        element.replaceWith(htmlText);

                        return this.link;
                    },
                    link:function(scope, element, attrs) {
                        scope.notimportant = eval('scope.' + attrs.property + '.append');                       
                    }
                }
            })
            .directive('formShowBtn', function() {
                return {
                    restrict: 'E',
                    replace:true,
                    scope:{},
                    template: '<button class="btn" ng-click="display()">Show</button>',
                    link:function(scope, element, attrs) {
                        scope.display = function() {
                            scope.$parent.display(attrs.property);
                        };
                    }
                }
            });

        function TestController($scope) {
            var testobjectsingle = {text: 'hello text', instance: {text: 'hello instance', append: 'ST'}};
            $scope.testobjectsingle = testobjectsingle;

            var testobjectarray = [];
            for (var i = 0 ; i < 2 ; i++) 
                testobjectarray.push( {text: 'hello text' + i,  instance: {text: 'hello instance' + i, append: 'ST'}} );

            $scope.testobjectarray = testobjectarray;

            $scope.display = function(value) {
                console.log( JSON.stringify($scope[value]) );
            };
        }
    </script>
</head>
<body>
    <div ng-app="TestApplication">
        <div ng-controller="TestController">
            <div style="padding:20px">
                <form-text-input data-property="testobjectsingle.text"></form-text-input>
                <form-object-input data-property="testobjectsingle.instance"></form-object-input>
                <form-show-btn data-property="testobjectsingle"></form-show-btn>
            </div>

            <div style="padding:20px">
                <div ng-repeat="singleelement in testobjectarray">
                    <form-text-input data-property="singleelement.text"></form-text-input>
                    <form-object-input data-property="singleelement.instance"></form-object-input>
                </div>
                <form-show-btn data-property="testobjectarray"></form-show-btn>
            </div>
        </div>
    </div>
</body>
</html>

非常感谢您的帮助!

亲切的问候, 的Matthias

编辑:小提琴的最佳选择应该是'没有换行' - 抱歉!

0 个答案:

没有答案