如何告诉角度在父模板中呈现子指令的位置(多次转换)?

时间:2016-06-21 08:01:51

标签: javascript angularjs angularjs-directive angular-directive

我遇到的问题是无法在父模板中呈现子指令(selected-item-template)。

代码如下:

HTML(主要/子指令)

<compact-select
    no-item-selected-text="Add a Customer"
    no-item-selected-icon="fa-user"
    search-placeholder="Type a customer name"
    cs-model="customer"
    cs-items="contacts"
>
    <display-item-template>
        <span>{{$parent.item.id}}</span>
        <span>{{$parent.item.name}}</span>
    </display-item-template>
    <selected-item-template>
       Your have selected customer: {{$parent.item.name}}
    </selected-item-template>
</compact-select>

指令

angular.module('core').directive('compactSelect', [function($timeout) {
    return {
        templateUrl : 'modules/core/views/components/compact-select-tpl.html',
        bindToController: true,
        transclude: true,
        scope: {
            noItemSelectedText: '@',
            noItemSelectedIcon: '@',
            csModel: '=',
            csItems: '=csItems'
        },
        controllerAs : 'ctrl',
        controller : function($scope) {

        }
    };
}]).directive('displayItemTemplate', function() {
    return {
        require: '^compactSelect',
        restrict: 'E'
    }
}).directive('selectedItemTemplate', function() {
    return {
        require: '^compactSelect',
        restrict: 'E'
    }
});

指令模板(modules / core / views / components / compact-select-tpl.html)

<div class="compact-select-repeater-box" style="" >
    <div ng-transclude ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)">
        <span>{{item.name}}</span>
        <span>{{item.id}}</span>
    </div>
    <div style="position:absolute;bottom:0">
        <a href="#">+ Click here to add customer {{ctrl.message}}</a>
    </div>
    **HERE I WANT SELECTED ITEM TEMPLATE**
</div>

问题:如何判断需要呈现子指令的位置?

关于ng-repeat的指令有效,但是当我添加两个指令时,所有内容都会组合在一起,而这不是我想要的。有没有办法用ng-transclude指定在哪里呈现哪个指令?像ng-transclude =“displayItemTemplate”和ng-transclude =“selectedItemTemplate”?

2 个答案:

答案 0 :(得分:0)

  

此示例基于指令,我想向您展示多指令如何在一个阵列上协同工作。

     

我希望这会对你有所帮助。

    var app = angular.module("app", []);

        app.controller("ctrl", function ($scope) {

            $scope.selectedList = [];

            $scope.data = [
                { name: "a", checked: true },
                { name: "b", checked: false }
            ];

            $scope.getResult = function () {
                console.log($scope.selectedList);
            }

        });

        app.directive("directiveA", [function () {
            return {
                restrict: "E",
                template: "<ul ng-repeat=\"item in items\">" +
                    "<li><directive-c data=\"item\"></directive-c> {{item.name}} <directive-b data=\"item\"></directive-b></li>" +
                    "</ul>",
                scope: {
                    items: "="
                }
            };
        }]);

        app.directive("directiveB", function () {
            return {
                restrict: "E",
                template: "<button ng-click=\"renderData(data)\">{{data.checked ? 'unchecked':'checked'}}</button>",
                scope: {
                    data: "="
                },
                link: function (scope) {

                    scope.renderData = function (data) {
                        data.checked = !data.checked;
                    }

                }
            }
        });

        app.directive("directiveC", function () {
            return {
                restrict: "E",
                template: "<input type=\"checkbox\" ng-model=\"data.checked\">",
                scope: {
                    data: "="
                }
            }
        });

        app.directive("directiveD", function () {
            return {
                restrict: "E",
                template: "<ul ng-repeat=\"item in items\">" +
                    "<li ng-if=\"item.checked\">{{item.name}}</li>" +
                    "</ul>",
                scope: {
                    items: "=",
                    result: "="
                },
                link: function (scope) {

                    scope.$watch("items", function (newValue) {
                        scope.result = [];
                        if (newValue) {
                            angular.forEach(scope.items, function (item, index) {
                                if (item.checked) scope.result.push(item);
                            });
                        }
                    }, true);


                }
            }
        });
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl">
<head>
    <title></title>
</head>
<body>

    <h3>items</h3>
  
    <directive-a items="data"></directive-a>

    <h3>selected items</h3>

    <directive-d items="data" result="selectedList"></directive-d>

    <hr />

    <button ng-click="getResult()">get selected list</button>
    <small>after click, check your console</small>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

</body>
</html>

答案 1 :(得分:0)

我已经想出如何实现以下目标。它可以通过多个transcludsions完成,因为角度为1.5。 我只需要定义transcludeSlot。

代码如下:

HTML(主要/子指令)

public static string ReadFileAndFetchStringInSingleLine(string file)
    {
        StringBuilder sb;
        try
        {
            sb = new StringBuilder();
            using (FileStream fs = File.Open(file, FileMode.Open))
            {
                using (BufferedStream bs = new BufferedStream(fs))
                {
                    using (StreamReader sr = new StreamReader(bs))
                    {
                        string str;
                        while ((str = sr.ReadLine()) != null)
                        {
                            sb.Append(str);
                        }
                    }
                }
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            return "";
        }
    }

<强>指令

<compact-select
    no-item-selected-text="Add a Customer"
    no-item-selected-icon="fa-user"
    search-placeholder="Type a customer name"
    cs-model="customer"
    cs-items="contacts"
>
    <display-item-template>
        <span>{{$parent.item.id}}</span>
        <span>{{$parent.item.name}}</span>
    </display-item-template>
    <item-selected-template>
       Your have selected customer: {{$parent.csModel.name}}
    </item-selected-template>
</compact-select>

指令模板(modules / core / views / components / compact-select-tpl.html)

angular.module('core').directive('compactSelect', [function($timeout) {
    return {
        templateUrl : 'modules/core/views/components/compact-select-tpl.html',
        bindToController: true,
        transclude: {
            'repeaterItemSlot': 'displayItemTemplate',
            'itemSelectedTemplateSlot' : 'itemSelectedTemplate'
        },
        scope: {
            noItemSelectedText: '@',
            noItemSelectedIcon: '@',
            csModel: '=',
            csItems: '=csItems'
        },
        controllerAs : 'ctrl',
        controller : function($scope) {

        }
    };
}]);

所以这与XAML非常相似。