自定义角度指令,数据绑定无法正常工作

时间:2016-11-08 14:08:14

标签: javascript angularjs data-binding

我是Angularjs的新手,并试图编写一个从存储库动态创建整个页面的指令。

以下是我在数组中的布局模拟,它被转换为父/子层次结构并存储在$ scope.layoutAsHierachy中。

我的指令只是迭代并编译layoutAsHierarchy图的每个元素。

现在页面创建正常,但不会发生数据绑定。我究竟做错了什么? 对于我想要实现的目标,是否有更好的角度解决方案?

        $scope.layout = [{ "id": 1, "parent_id": 0, "name": "root", "html": "<div class=\"rootContainer\" style=\"float:left; width:100%;\"/>" }, //root
                        { "id": 2, "parent_id": 1, "name": "first row", "html": "<div class=\"row1\" style=\"height:15%;\"/>" }, //first row for header
                        { "id": 3, "parent_id": 1, "name": "second row", "html": "<div class=\"row2\" style=\"height:85%;\"/>" }, //second row
                        { "id": 4, "parent_id": 3, "name": "second row, left column", "html": "<div class=\"column1\" style=\"float:left; width:50%;\"/>" }, //second row, left column
                        { "id": 5, "parent_id": 3, "name": "second row, right column", "html": "<div class=\"column2\" style=\"float:left; width:50%;\"/>" }, //second row, right column
                        { "id": 6, "parent_id": 4, "name": "second row, left column, QR Code", "html": "<center>Bar / QR Code<br/><input ng-model=\"buildModel.ProccesableMoveable.Model.QRCode\"autofocus class=\"text-center\" type=\"text\" style=\"width:200px; height:30px; font-size:28px;\" ng-keyup=\"loadData($event)\"/></center><br/>" }, //second row, left column QR Code
                        { "id": 7, "parent_id": 4, "name": "second row, left column, Item Table", "html": "<center><input ng-model=\"buildModel.ProccesableMoveable.Model.RedNumber\" type=\"text\" style=\"width:110px;vertical-align:central\" readonly/><input ng-model=\"buildModel.ProccesableMoveable.Model.OrderNumber\" type=\"text\" style=\"width:110px\" readonly/></center><center><input ng-model=\"buildModel.ProccesableMoveable.Model.Species\" class=\"text-center\" type=\"text\" style=\"vertical-align:central;width:110px\" readonly/><input ng-model=\"buildModel.ProccesableMoveable.Model.Width\" class=\"text-center\" type=\"text\" style=\"vertical-align:central;width:110px\" readonly/></center><center><input ng-model=\"buildModel.ProccesableMoveable.Model.Color\" class=\"text-center\" type=\"text\" style=\"vertical-align:central;width:110px\" readonly/><input ng-model=\"buildModel.ProccesableMoveable.Model.ItemNumber\" class=\"text-center\" type=\"text\" style=\"vertical-align:central;width:110px\" readonly/></center>" }, //second row, left column Item Table
                        { "id": 8, "parent_id": 4, "name": "second row, left column, Item Description", "html": "<br/><br/><center>Door Type<br/><input name=\"txtDoorType\" class=\"text-center\" type=\"text\" style=\"width:200px; height:30px; font-size:28px;\"/></center>" }, //second row, left column Item Description
                        { "id": 9, "parent_id": 5, "name": "second row, right column, Moveable Table", "html": "<div style=\"width:100%\"><center><table border=\"1\"><thead style=\"border-bottom:double;font-weight:bold\"><tr><td style=\"text-align:center;width:100px\">Doors</td><td style=\"text-align:center;width:100px\">Rack#</td></tr></thead><tr ng-repeat=\"(DoorId, Description) in processableMoveable.Model.Moveable\"><td width=\"100\" style=\"text-align:center\">{{DoorId}}</td><td width=\"175\" style=\"text-align:center\">{{Description}}</td></tr></table></center></div>" }, //second row, right column Moveable Table
                        { "id": 10, "parent_id": 2, "name": "first row, header", "html": "<center><h2>Some place</h2><h3>Locator - Sort</h3></center>" }]; //first row, header];

    $scope.layoutAsHierarchy = unflatten($scope.layout);

指令代码:

function wwAppsecLayout($compile) {
    return {
        restrict: "E",
        scope: { collection: '=' },
        link: function (scope, element, attrs) {
            if (angular.isArray(scope.collection)) {
                angular.forEach(scope.collection, function (value, key) {
                    var c = $compile(value.html)(scope);
                    element.replaceWith(c);
                    buildHierachy($compile, scope, c, value.children);
               });
            }
        }
    };
};
app.directive('wwAppsecLayout', ['$compile', wwAppsecLayout]);

function buildHierachy($compile, scope, element, collection) {
    if (angular.isArray(collection)) {
        angular.forEach(collection, function (value, key) {
            var c = $compile(value.html)(scope);
            element.append(c);
            buildHierachy($compile, scope, c, value.children);
        });
    }
};

1 个答案:

答案 0 :(得分:0)

好吧,我最终做了以下工作,这是有效的。

<ww-appsec-layout layout="layoutAsHierarchy"></ww-appsec-layout>

function wwAppsecLayout($compile ) {
    return {
        restrict: "E",
        scope: true,
        link: function (scope, element, attrs) {
            if (!angular.isUndefined(attrs.layout)) {
                var layout = scope.$eval(attrs.layout);
                if (angular.isArray(layout)) {
                    angular.forEach(layout, function (value, key) {
                        var c = $compile(value.html)(scope);
                        element.replaceWith(c);
                        buildHierachy($compile, scope, c, value.children);
                    });
                }
            }
        }
    };
};
app.directive('wwAppsecLayout', ['$compile', wwAppsecLayout]);

function buildHierachy($compile, scope, element, collection) {
    if (angular.isArray(collection)) {
        angular.forEach(collection, function (value, key) {
            var c = $compile(value.html)(scope);
            element.append(c);
            buildHierachy($compile, scope, c, value.children);
        });
    }
};

然而以下几乎是有效的。除了我的ng-keyup =“(loadData($ event))”不起作用。我猜我的隔离范围不知道loadDataFunction。关于我如何做到这一点的任何想法?

<ww-appsec-layout layout="layoutAsHierarchy" ng-model="buildModel"></ww-appsec-layout>

function wwAppsecLayout($compile)
{
    return {
        restrict: "E",
        scope: { layout: '=', model: '=ngModel' },
        require: 'ngModel',
        link: linker,
        replace: true
    };

    function linker(scope, element, attrs, ctrl) {
        if (angular.isArray(scope.layout)) {
            angular.forEach(scope.layout, function (value, key) {
                var c = $compile(value.html)(scope);
                element.replaceWith(c);
                buildHierachy($compile, scope, c, value.children);
            });

            scope.$watch('model', function (newValue, oldValue) {
                if (!angular.isUndefined(newValue) && newValue != null)
                    scope.buildModel = newValue;
            });

        }
    }

};
app.directive('wwAppsecLayout', ['$compile', wwAppsecLayout]);

function buildHierachy($compile, scope, element, collection) {
    if (angular.isArray(collection)) {
        angular.forEach(collection, function (value, key) {
            var c = $compile(value.html)(scope);
            element.append(c);
            buildHierachy($compile, scope, c, value.children);
        });
    }
};
相关问题