Javascript 指令不继承控制器';s范围

Javascript 指令不继承控制器';s范围,javascript,angularjs,model-view-controller,angularjs-directive,angularjs-scope,Javascript,Angularjs,Model View Controller,Angularjs Directive,Angularjs Scope,我设置了一个控制器,其中包含一些用于表单验证的函数。在这个控制器$scope中,我有一个数组$scope.errorMsgs,其中填充了用户在填写表单时发出的错误消息字符串 我还有一个显示此表单的指令。它们都连接到同一个模块。控制器和指令位于同一目录中的不同文件中。但是,指令链接函数中的作用域不引用控制器中的$scope。事实上,它们有不同的$ID。你知道为什么会这样吗 模块: angular.module('aop.availabilitysolver', [ 'aop.service

我设置了一个控制器,其中包含一些用于表单验证的函数。在这个控制器$scope中,我有一个数组$scope.errorMsgs,其中填充了用户在填写表单时发出的错误消息字符串

我还有一个显示此表单的指令。它们都连接到同一个模块。控制器和指令位于同一目录中的不同文件中。但是,指令链接函数中的作用域不引用控制器中的$scope。事实上,它们有不同的$ID。你知道为什么会这样吗

模块:

angular.module('aop.availabilitysolver', [
    'aop.services',
    'checklist-model'
]).run(['widgetService', function(widgetService) { 'use strict';
    widgetService.registerWidgets([
        {
            title: 'AVAILABILITYSOLVER.WIDGETS.AVAILABILITYSOLVER',
            translatableDescription: 'AVAILABILITYSOLVER.WIDGETS.AVAILABILITYSOLVER',
            type: 'aop-availability-solver',
            configuration: {},
            width: 1
        }
    ]);
}]);
控制器

angular.module('aop.availabilitysolver')
    .controller('AvailabilitySolverController', ['$scope',
        function ($scope) { 'use strict';
            //console.log($scope);
            $scope.selectGoalDropdown = ['Impressions', 'Spend'];
            $scope.selectGoalTimespan = ['Day', 'Week', 'Month'];

            $scope.selectGoals = [
                {
                    id: '1',
                    name: 'Impressions'
                },
                {
                    id: '2',
                    name: 'Spend'
                }
            ];

            $scope.selectTimespan = [
                {
                    id: '4',
                    name: 'Day'
                },
                {
                    id: '5',
                    name: 'Week'
                },
                {
                    id: '6',
                    name: 'Month'
                }
            ];
            $scope.selectedItem = 'test2';
            $scope.selectedItem1 = 'test3';

            $scope.per = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20];
            $scope.hours = [1, 3, 4, 12, 24, 36, 48, 72, 120, 168];
            $scope.uncpd = ['uncapped'];
            $scope.times = {
                amt: [],
                freq: [],
                uncapped: []
            };
            $scope.caps = [];

            $scope.quantity;

            $scope.level = 'Fcap';

            $scope.showErrors = false;
            $scope.errorMsgs = [];

            $scope.calculateFreqCaps = function(amt, freq, uncap) {
                var rtn = [];
                function isNothingSelected() { // No selections made
                    if(amt.length === 0 && freq.length === 0 && uncap.length === 0) {
                        rtn.push('Please choose frequency settings or select \'uncapped.\'');
                        $scope.errorMsgs.push('Please choose frequency settings or select \'uncapped.\'');
                    }
                }
                function malformedFrequencyOpts() { // Selected amount but no frequency & vice versa
                    if((amt.length > 0 && freq.length === 0) || (amt.length === 0 && freq.length > 0)) {
                        rtn.push('Please select both an amount and a frequency.');
                        $scope.errorMsgs.push('Please select both an amount and a frequency.');
                    }
                }
                function selectedTooMuch() { // Uncapped and frequency settings selected
                    if((amt.length > 0 || freq.length > 0) && uncap.length === 1) {
                        rtn.push('Choose uncapped only if no amount or frequency is selected');
                        $scope.errorMsgs.push('Choose uncapped only if no amount or frequency is selected');
                    }
                }
                isNothingSelected();
                malformedFrequencyOpts();
                selectedTooMuch();
                if(rtn.length > 0) {
                    return rtn;
                } else if (amt.length === 0 && freq.length === 0 && uncap.length === 1) { // Only uncapped selected
                    return ['uncapped'];
                }
                angular.forEach(amt, function (a) {
                    angular.forEach(freq, function (f) {
                        rtn.push(a + '/' + f + 'h');
                    });
                });
                return rtn;
            };

            $scope.validateSelectGoalQuantity = function(n) {
                if(!Number(n)) {
                    $scope.errorMsgs.push('Quantity must be a number');
                    return false;
                }
                return true;
            };

            $scope.submitBtnClick = function() {
                // Build Frequency cap JSON object
                $scope.caps = $scope.calculateFreqCaps($scope.times.amt, $scope.times.freq, $scope.times.uncapped);
                $scope.validateSelectGoalQuantity($scope.quantity);
                if($scope.errorMsgs.length > 0) {
                    console.log($scope.errorMsgs);
                    // Show error message div and clear $scope.errorMsgs
                    $scope.showErrors = true;
                    //$scope.errorMsgs.length = 0;
                }
                else {
                    $scope.showErrors = false;

                }
            };
}]);
指令

angular.module('aop.availabilitysolver')
    .directive('aopAvailabilitySolver', ['$filter', function($filter) { 'use strict';
        return {
            restrict: 'E',
            link: function(scope, element, attrs) {
                angular.noop(attrs);
                // Hide error div initially
                $('.availabilitySolverErrorDisplay').hide();

                var i = element.find('.levelRadio :radio');
                i.on('click', function() {
                    if($(i[0]).prop('checked')) {
                        scope.level = 'Fcap';
                        element.find('.freqCapDiv').show();
                    }
                    else {
                        scope.level = 'Bid';
                        element.find('.freqCapDiv').hide();
                    }
                });
                console.log(scope);
            },
            templateUrl: 'features/availabilitySolver/availabilitySolver.html'
        };
    }]);
HTML

<div ng-controller="AvailabilitySolverController">
    <div class="container-fluid availabilitySolverScreen1">
        <div class="row">
            <div class="alert alert-danger availabilitySolverErrorDisplay">
            </div>
        </div>
        <div class="row">
            Campaign Selector
        </div>
        &nbsp;
        <!-- Goals -->
        <div class="row">
            <h5>Select Goal</h5>
            <form name="selectGoalForm" novalidate>
                <div class="col-md-4">
                    <button name="goals" class="btn btn-default" ng-model="selectedItem" ng-options="value.id as value.name for (key, value) in selectGoals" data-style="btn-primary" bs-select></button>
                </div>

                <div class="col-md-4">
                    <div class="col-md-10">
                        <input type="number" name="quantity" class="form-control" placeholder="Quantity" ng-model="quantity">
                    </div>

                    <div class="col-md-2">
                        per
                    </div>
                </div>

                <div class="col-md-4">
                    <button name="timespan" class="btn btn-default" ng-model="selectedItem1" ng-options="value.id as value.name for (key, value) in selectTimespan" data-style="btn-primary" bs-select></button>
                </div>
            </form>
        </div><!-- End goals -->
        &nbsp;
        <!-- Level cap -->
        <div class="row">
            <h5>Level</h5>
            <div class="col-md-12">
                <form class="levelRadio">
                    <input name="level" value="Fcap" type="radio" checked> Fcap &nbsp;
                    <input name="level" value="Bid" type="radio"> Bid
                </form>
            </div>
        </div><!-- end level cap -->
        &nbsp;
        <!-- Frequency cap analysis -->
        <div class="row freqCapDiv">
            <h5>Customize Frequency Cap for Analysis</h5>
            <div class="col-md-8">
                <!-- per -->
                <div class="col-md-4">
                    <ul>
                        <li ng-repeat="item in per">
                            <input type="checkbox"
                                   checklist-value="item"
                                   checklist-model="times.amt" /> {{item}} per
                        </li>
                    </ul>
                </div><!-- end per -->

                <!-- hour(s) -->
                <div class="col-md-4">
                    <ul>
                        <li ng-repeat="item in hours">
                            <input type="checkbox"
                                   checklist-value="item"
                                   checklist-model="times.freq" /> {{item}} hr
                        </li>
                    </ul>
                </div>

                <!-- uncapped -->
                <div class="col-md-4">
                    <ul>
                        <li ng-repeat="item in uncpd">
                        <input type="checkbox"
                               checklist-value="item"
                               checklist-model="times.uncapped" /> uncapped
                    </ul>
                </div>
            </div>
            <div class="col-md-4">

            </div>
        </div><!-- end frequency cap analysis -->
        &nbsp;
        <!-- submit button -->
        <div class="row">
            <button class="btn btn-primary" ng-click="submitBtnClick()">Submit</button>
        </div>
    </div>
</div>

活动选择器
选择目标
每
水平仪
Fcap
投标
自定义频率上限以进行分析
  • {{item}}per
  • {{item}}hr
  • 无盖
提交
为什么所有jQuery-in指令?
link
中的所有内容都可以使用angular内置指令来完成,如
ng show
ng model
我是angular新手,仍在学习“angular way”。最好的学习方法是将jQuery从页面中删除。一旦开始实现数据绑定,整个指令可能会变成一个
ng include
,您必须查看一些html来查看作用域的嵌套位置,我不知道您在做什么。我在html中找不到该指令,只能在
registerWidgets
中找到。我不知道registerWidgets的作用。建议您在plunker中进行演示,以复制此问题。