首页 > 解决方案 > 绑定到 AngularJS 中的嵌入

问题描述

我不确定我正在尝试做的事情是否正确,所以如果整个前提是错误的,请给我一个“更正确”的选项。

我有一个 AngularJS 1.5.11 应用程序。我正在尝试创建一个通用的模态 html 标记,可以在需要模态的任何地方在整个应用程序中使用。我有一个看起来像这样的页面模板:

<form class="page-sidebar-container" data-name="mainForm">
    <div class="page-sections">
        <div class="form-columned form-columned-1">
            <div class="form-row">
                <div class="section column column-0 span-0" id="section-JobFromType">
                    <h4 class="section-heading">From Type</h4>


                    <div class="columns gutters-large">
                        <div style="display: table;margin: 18px 0px;">

                            <api-select label="Type" items="fromTypeItems" item="selectedFromType" required>
                            </api-select>


                        </div>

                    </div>
                </div>

                <div class="section column column-1 span-0" id="section-JobToType">
                    <h4 class="section-heading">To Type</h4>
                    <div class="columns gutters-large">
                        <div style="display: table;margin: 18px 0px;">

                            <api-select label="Type" items="toTypeItems" item="selectedToType"
                                read-only="toTypeDisabled" required>
                            </api-select>


                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</form>


<api-modal is-open="entitySelectOpen" label="{{entitySelectLabel}}">
    <modal-body>
        {{$id}}
        <api-select label="{{entitySelectParentLabel}}" items="entitySelectParentItems" item="selectedEntitySelectParent" required>
        </api-select>
    
        <api-select label="{{entitySelectChildLabel}}" items="entitySelectChildItems" item="selectedEntitySelectChild" read-only="entitySelectChildDisabled" required>
        </api-select>
    
        <api-select label="{{entitySelectEntityLabel}}" items="entitySelectEntityItems" item="selectedEntity" read-only="entitySelectEntityDisabled" required>
        </api-select>
    </modal-body>
    <modal-actions>
        {{$id}}
        <api-button label="{{modalPrimaryActionLabel}}" type="primary" icon="icon-checkmark" on-click="modalPrimaryActionClick"></api-button>
        <api-button label="Return" type="return" icon="icon-cancel" on-click="modalReturnActionClick"></api-button>
    </modal-actions>
</api-modal>

使用以下控制器:

(function (angular) {
    angular.module('views.jobcontrol', [
        'ngRoute',

        'components.formApiControlSelect',
        'components.formApiControlText',
        'components.formApiModal'
    ])
        .config([
            '$routeProvider',
            function ($routeProvider) {
                'use strict';
                var route = {
                    templateUrl: 'modules/apiViews/jobcontrol/jobcontrol-view.html',
                    controller: 'JobControlController',
                    reloadOnSearch: false,
                    caseInsensitiveMatch: true
                };
                $routeProvider
                    .when('/view/jobcontrol/:action/:jobNumber/?', route);
            }
        ]).controller('JobControlController', [
            '$scope',
            '$timeout',
            '$routeParams',
            function ($scope, $timeout, $routeParams) {
                'use strict';

                function generateMockGuid() {
                    var result, i, j;
                    result = '';
                    for (j = 0; j < 32; j++) {
                        if (j == 8 || j == 12 || j == 16 || j == 20)
                            result = result + '-';
                        i = Math.floor(Math.random() * 16).toString(16).toUpperCase();
                        result = result + i;
                    }
                    return result;
                

                function option(label,value){
                    return {
                        value:value,
                        label:label
                    }
                }

                
                $scope.fromTypeItems = [option("test",1)];
                $scope.selectedFromType = null;
                $scope.$watch('selectedFromType', function (){
                    console.log("do something");
                });


                /* to type */
                $scope.fromTypeItems = [option("test",1)];
                $scope.selectedToType = null;
                $scope.toTypeDisabled = true;
                $scope.$watch('selectedToType', function () {
                    console.log("do something else");
                });

                

                
                /* entity select modal */


                $scope.selectedFromEntity = null;
                $scope.selectedToEntity = null;

                $scope.entitySelectParentItems = [option("parent 1", generateMockGuid()),option("parent 2", generateMockGuid()),option("parent 3", generateMockGuid())];
                $scope.entitySelectChildItems = [option("child 1", generateMockGuid()),option("child 2", generateMockGuid()),option("child 3", generateMockGuid())];
                $scope.entitySelectEntityItems = [option("entity 1", generateMockGuid()),option("entity 2", generateMockGuid()),option("entity 3", generateMockGuid())];

                $scope.selectedEntity = null;
                $scope.$watch('selectedEntity', function () {
                    console.log('selectedEntity has changed to ' + $scope.selectedEntity);
                });
                
                function clearModalSelections(){
                    console.log($scope);
                    $scope.selectedEntitySelectParent = null;
                    $scope.selectedEntitySelectChild = null;
                    $scope.selectedEntity = null;
                }


                $scope.modalPrimaryActionLabel = "Next";

                $scope.modalPrimaryActionClick = function(){
                    clearModalSelections();
                    $scope.entitySelectOpen = false;
                }

                $scope.modalReturnActionClick = function(){
                    clearModalSelections();
                    $scope.entitySelectOpen = false;
                }
            }
        ]);
})(window.angular);

模态有效,其中包含 myapi-buttonapi-select',并且' 的项目使用添加到,和数组api-select的 3 个选项正确填充。问题是$scope.entitySelectParentItems$scope.entitySelectChildItems$scope.entitySelectEntityItems

$scope.$watch('selectedEntity', function () {
    console.log('selectedEntity has changed to ' + $scope.selectedEntity);
});

永远不会被调用。如果我将三个api-select's 移出 theapi-modal > modal-body并移出与 the 相同的级别,api-modal那么一切都按预期工作(除了他的元素在基页上,而不是在模态中),但是一旦一切都在模态中,我无法访问用户何时选择一个值以及该值是什么。

我确定这一定与具有单独范围的嵌入有关,但我很困惑。模态中的 transclude如何api-select访问其项目的主要范围以填充选择列表,甚至在列表更新时更新,但是当用户选择某些内容时,它不会像对其他内容一样绑定回范围api-select的页面上。我使用 ng-transclude 错误吗?这是一件可以做的事情,但我错过了一步吗?

万一这很重要,javascript forapi-modal看起来像这样:


angular.module('components.formApiModal',[
    'components.formApiButton'
])
.directive('apiModal', ['$timeout', '$compile', function ($timeout, $compile) {
    'use strict';
    return {
        restrict: 'E',
        templateUrl: 'modules/apiComponents/generic/modal/modal-template.html',
        controller: 'apiModalController',
        transclude: {
            'body': 'modalBody',
            'actions': 'modalActions'
          },
        scope: {
            isOpen: "=",
            label: '@',
            actions: "="
        },
        link: function (scope, element, attrs) {

        }
    };
}])
.controller('apiModalController', ['$scope', function($scope) {

}]);

和模板:

<div class="modal-backdrop modal-large" data-ng-class="{'modal-closed' : !isOpen }">
    <div class="modal-container">
        <div class="modal" data-ng-click="$event.stopPropagation()">
            <h1 class="modal-header" >{{label}}</h1>
            <div class="modal-body">
                <div class="form-messages" data-ng-if="formPage.overrideConfirmationMessages.length">
                    <div class="form-header-errors">

                    </div>
                </div>
                <h4 class="section-heading" data-ng-if="section.altHelp">{{section.altHelp}}</h4>
                <div class="columns gutters-large">
                    <div ng-transclude="body"></div>
                </div>
            </div>
            <div class="modal-footer" >
                <div ng-transclude="actions"></div>
               
            </div>
        </div>
    </div>
</div>

标签: javascriptangularjs

解决方案


推荐阅读