【问题标题】:Nesting (first) custom directive another (second) directive moves (first) custom directive to childscope instead of scope嵌套(第一个)自定义指令另一个(第二个)指令将(第一个)自定义指令移动到子作用域而不是作用域
【发布时间】:2019-05-29 22:40:16
【问题描述】:

以下是一个模板,它的工作原理是 webix-ui 指令指向子作用域,因为它位于 ng-if 内...

在初始化 ui 组件配置对象之前,我需要 ng-if 等待 $scope.init() 完成获取数据。

如何在我的 webix-ui 指令中指向范围,而不是子范围?

   <div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController" get-risk>
        <div id="mycreateform" class="container" type="space" layout-padding="">     
            <form id="form" name="CreateRisk" role="form" ng-submit="valid() && submit()" novalidate>
                <div id="details" class="layout table" border="1">                               
                    <div class="tr">
                        <div class="td label">
                            Title
                        </div>
                        <div class="td locked">
                           <div ng-if="initDone">
                              <div webix-ui="config.risktitle" width="500" 
                                   height="30" type="text" id="risktitle"
                                   name="risktitle">
                              </div>
                            </div>
                        </div>
                    </div>
                </div>
            </form>
         </div>
    </div>

这正确地指向范围,因为它没有嵌套在 ng-if 中

angular.module('Risk').directive('getRisk', getRisk); 

function getRisk(){
     return {
            restrict: 'A',
            controller: function ($scope, $http, $sce){

                $scope.risklevels = {
                    riskmaximum: '',
                    riskhigh: '',
                    riskmedium: '',
                    riskminimum: ''
                }

                $scope.riskMatrix = [];
                for(var l = 1; l <= 5; l++)
                {
                    $scope.riskMatrix[l] = [];
                    for (var c = 0; c <= 5; c++)
                    {
                        $scope.riskMatrix[l][c] = '';  
                    }
                }

                $scope.initDone = false;

                $scope.init = function(){
                      angular.element(document.querySelector('link[href="/app/tool/risk/CreateRisk.css"]')).remove();
                      angular.element(document.querySelector('head')).append('<link type="text/css" rel="stylesheet" href="/app/tool/risk/CreateRisk.css"/>'); 

                      return $http.get('/api/riskconfig').then(function(response){
                           if (response.data.Succeeded){
                                $scope.risklevels.riskmaximum = response.data.Result.Levels[0].riskmaximum;
                                $scope.risklevels.riskhigh = response.data.Result.Levels[0].riskhigh;
                                $scope.risklevels.riskmedium = response.data.Result.Levels[0].riskmedium;
                                $scope.risklevels.riskminimum = response.data.Result.Levels[0].riskminimum; 


                                for (var idx = 0; idx < response.data.Result.Thresholds.length; idx++)
                                {
                                    var l = response.data.Result.Thresholds[idx].likelihood;
                                    var c = response.data.Result.Thresholds[idx].consequence;
                                    v = response.data.Result.Thresholds[idx].level;
                                    $scope.riskMatrix[l][c] = v;
                                }

                                return response.data.Result;
                           }
                           else{
                                $scope.msg = $sce.trustAsHtml(response.data);
                           }
                      });
                } 

                $scope.init().then(function(){
                    $scope.initDone = true;
                    return $scope.initDone;
                });
            } 
     }  
}

目前 This 指向 ChildScope(应该指向 Scope 而不是),因为它嵌套在模板中的 ng-if 中

angular.module('Risk').directive('webixUi', WebixElement);

function WebixElement(DOMops, ValidationService){                   
      var directive = {
            restrict: 'A',
            link: linkFn,
            controller: webixUiController,
            bindToController: true
      }

      function linkFn(scope, element, attrs) {                       
      }

      return directive;            
}


function webixUiController($scope, $attrs, DOMops, ValidationService){
    var attr = $attrs.name;
    var type = $attrs.type;
    var width = $attrs.width;
    var height = $attrs.height;
    var maxlength = $attrs.hasOwnProperty('maxlength')? $attrs.maxlength: null;  

    var view;
    if (type == "level")
        view = "text";
    else
        view = type;

    var config = 
    {
        view: view,
        value: $scope.risk[attr],      
        on: {
            "onTimedKeyPress": function(code){  
                var obj = this.eventSource || this; 
                ValidationService.handleKeyPress(obj, code, attr);
                if (type == "level")
                    DOMops.assignRiskLevel(scope, obj); 
            },
            "onBlur": function(code){  
                var obj = this.eventSource || this;  
                ValidationService.updateAndValidate(obj,code,attr); 
            }
        },
        responsive: true,
        width: width,
        height: height
    };
    if (maxlength)
        config.attributes = {maxlength : maxlength};
    $scope.config[$attrs.name] = config; 
} 

【问题讨论】:

  • 我正在尝试使所有指令成为scope 的一部分,而不是整个模板上的childscope

标签: angularjs angularjs-directive scope directive


【解决方案1】:

从属性组件设置值的一种方法是使用scope.$eval 手动评估表达式属性:

$scope.$eval($attrs.onConfig, {$config: config}); 

用法:

<div webix-ui="config.risktitle" width="500" 
     height="30" type="text" id="risktitle"
     name="risktitle" on-config="config.risktitle = $config">
</div>

当指令初始化时,它会评估 on-config 属性中的表达式,并将 $config 作为本地表达式。

作用域继承通常是直截了当的......直到您需要在子作用域中进行 2 路数据绑定(即表单元素、ng-model)。 Ng-repeatng-switchng-include 如果您尝试从子作用域内绑定到父作用域中的原语(例如,数字、字符串、布尔值),可能会绊倒您。它不像大多数人期望的那样工作。子作用域拥有自己的属性,该属性隐藏/隐藏同名的父属性。

使其工作的方法是在模型的父对象中定义对象,然后在子对象中引用该对象的属性。

所以在父控制器中定义对象:

 $scope.config = {};

这遵循“总是有一个 '.' 的最佳做法。在你的模型中”。

有关详细信息,请参阅

【讨论】:

  • $scope.config = {} 实际上已经存在于我的模块控制器中,因为我阅读了对我的模型使用点方法的内容。唯一的问题是,eval 和 scope.config 是否需要一起使用?
  • 另外$scope.init().then(function(){ $scope.initDone = true }) 已经存在于我的代码中,那么我如何以比我在问题中使用的ng-if 方法更合适的方式使用$scope.initDone?基本上我想等待一个范围变量为真,然后评估一个语句,即 $scope.someConfig = config object;
  • stackoverflow.com/questions/28388452/… 是我正在尝试做的,但这样做会导致这个孤立的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2020-10-28
  • 2017-12-14
  • 2012-02-20
  • 2016-07-05
  • 2019-10-14
相关资源
最近更新 更多