【问题标题】:How to manage controller scope inside directive for particular event?如何在特定事件的指令内管理控制器范围?
【发布时间】:2017-04-19 10:00:13
【问题描述】:

我在控制器中定义了范围对象,称为

      $scope.labelEdit.Data  = {'lblCtrlEdit' : false, 'lblCtrlView' : true, 'inputShow': ''};

我正在指令内的指令(子指令)内访问此范围。我可以访问。

我的要求是要根据范围值显示标签或输入。 例如:指令代码

bosAppModule.directive('webFactoryCellControlLabel',function($compile, $timeout, webFactoryEvents){
    var layoutTableCellControlLabelObj={};

    linkFnTableCellControlLabel=function(scope, element, attributes, controllerCtrl) {
        //console.log("## webFactoryCellControlLabel");
        scope.labelData="";     
        scope.lblShow = true;
        scope.hideLblEditing = function () {
           $timeout(function() {                
               scope.labelCtrlEdit.lblCtrlEdit = false; 
                scope.labelCtrlEdit.lblCtrlView = true; 

            }, 2000);  // 2000ms delay   

        };
    };

    layoutTableCellControlLabelObj.scope={controlId:'=',attributeId:'=',layoutData:'=',pageObject:'=', cellId:'=',lblProperties: '=', attrModel: '=', labelCtrlEdit:'=', lblShow: '='};
    layoutTableCellControlLabelObj.restrict='AE';
    layoutTableCellControlLabelObj.replace='true';
    layoutTableCellControlLabelObj.transclude='true';
    layoutTableCellControlLabelObj.template = "<div "
            + "layout-data='layoutData' "
            + "page-object='pageObject' "
            + "label-ctrl-edit ='labelCtrlEdit'"            
            + "class='col-xs-12 col-sm-12 col-md-6 col-lg-6' "
            + "style='padding-right:0px;padding-left:0px;padding-top: 0;' "             
            + ">" 
            + "<label ng-show='labelCtrlEdit.lblCtrlView' class='k-label pull-right control-label' style='padding-top: 8px'><div><span style='{{setLabelStyle()}}'>{{labelData}}</span> &nbsp;  : &nbsp; &nbsp; </div></label>"
            + "<div ng-if='cellId == labelCtrlEdit.inputShow'>"
            +" <input focus-on='labelCtrlEdit.lblCtrlEdit'  ng-show='labelCtrlEdit.lblCtrlEdit' type='text' ng-mouseleave='hideLblEditing()' style='margin-right: 10px' class='k-textbox pull-right' ng-model='pageObject.collections.objectattribute.rowset[attrIndex].objectattributelabelname'/> "
            +"</div>"
            + "</div>";

    layoutTableCellControlLabelObj.link = linkFnTableCellControlLabel;


    return layoutTableCellControlLabelObj;  
});

在上面的代码中有模板,我想显示基于标签或输入的范围值。它正在工作,但它适用于所有标签,因为范围值以两种方式绑定发生变化。 我如何才能实现特定单元格只得到改变。

bosAppModule.directive('webFactoryCell',function($compile,$timeout, webFactoryEvents){

    var containerCellObj={};

    linkFnContainerCell = function(scope, element, attributes) {    

        var bindingtypeid = scope.cell.weblayoutcellbindingtypeid;
        scope.cellclass='';
        scope.cellProperties = {};
        if(scope.selectedDevice=="ipad"){
            //update the we
        }

        if(scope.cell.weblayoutcellsubcontainer=="false"){
            switch (bindingtypeid) {
            case "43334FBD-23A7-42E9-B737-88642E2F8BB1":
                //console.log("## NORMAL CONTROL");
                //scope.cellclass='webcell webnormalcellstyle col-lg-6 col-md-6 col-sm-4 col-xs-3';
                //NORMAL CONTROL
                /*angular.forEach(scope.layoutData.collections.webcontainer.rowset,function(containerValue,containerKey){
                if(containerValue.webcontainerid==scope.cell.weblayoutcellcontainerid) {*/

                    element.append("<web-factory-cell-control " 
                            + "ng-if='cellcontrol.layouttablecellcontrolcellid==cell.weblayoutcellid' "
                            + " ng-repeat='cellcontrol in layoutData.collections.layouttablecellcontrol.rowset' " 
                            + "control-id='cellcontrol.layouttablecellcontrolcontroltypeid' "                   
                            + "cell-controldata='cellcontrol'"  
                            + "label-ctrl-edit ='labelCtrlEdit'"                            
    //                      + " cellclass={{cellclass}} "
                            + "></web-factory-cell-control>");
                /*  }
                });*/

                break;


            default:
                break;
            }



        }


        scope.cellClick=function(event){
            //console.log("jfksdjfjs"+event.target.data.class+$(event.target).attr("class"));

            webFactoryEvents.setWebFactoryEventsData({selectedCellId:$(event.target).closest(".webcell").attr("id")});
            var eventsDataObj = webFactoryEvents.getWebFactoryEventsData();         
            var attributeId =  $('#'+ eventsDataObj.selectedCellId).find('label').parent('div').attr('attrid');
            if(attributeId) {
                webFactoryEvents.setWebFactoryEventsData({selectedCellId:eventsDataObj.selectedCellId,
                                                          attributeId:attributeId});
            }


            webFactoryEvents.cellClickEvent(event);


            if(eventsDataObj.selectedCellId == scope.cell.weblayoutcellid) {
                scope.labelCtrlEdit.inputShow = eventsDataObj.selectedCellId;
                scope.labelCtrlEdit.lblCtrlView = true;
            }


        };



        scope.labelControlEditing = function() {    
                scope.labelCtrlEdit.lblCtrlEdit = true; 
                //scope.labelCtrlEdit.lblCtrlView = false;
                //scope.labelCtrlEdit.inputShow = false;
                $timeout(function() {   
                    scope.$broadcast('labelCtrlEdit.lblCtrlEdit');
                }, 10);
        };



        $compile(element.contents())(scope);
    };

    //containerCellObj.transclude='true';
    containerCellObj.restrict='AE';
    containerCellObj.replace='true';
    containerCellObj.scope={layoutData:'=',pageObject:'=',mapperData:'=',cell:'=',cellclass:'=',selectedDevice:'=',labelCtrlEdit:'='};
    containerCellObj.template = "<div "
            + "layout-data='layoutData' "
            + "page-object='pageObject' "
            + "mapper-data='mapperData' "   
            + "selected-device='selectedDevice' "
            + "label-ctrl-edit ='labelCtrlEdit'"        
//          + "class='webcell webcellstyle col-lg-6 col-md-6 col-sm-4 col-xs-3' " 
            + "ng-class='getCellClass()' " 
            + " cellid='{{cell.weblayoutcellid}}' " 
            + " id='{{cell.weblayoutcellid}}' "
            + " ng-click='cellClick($event)' "
            + " ng-dblclick='cellDblClick($event)' "            
            + " > " 
//          + "{{cell.weblayoutcellorderno}}##Cell{{cell.weblayoutcellid}}"
            + "<div class='webcell-settings webcontrol-settings'" 
            + " ng-class='{commandcellhandle:(cell.weblayoutcellbindingtypeid ==\"0d430cc8-7d7e-4fbb-8ba0-67b7fb9605fa\"),cellhandle:(cell.weblayoutcellbindingtypeid !=\"0d430cc8-7d7e-4fbb-8ba0-67b7fb9605fa\")}' "
            + ">" 
            + " <ul><li>"
            +"<a><i id='editlabel' class='fa fa-pencil' ng-click='labelControlEditing()'></i></a>"          
            +"<a><i id='repeat' class='fa fa-repeat disabledfornow' ></i></a>"
            +"<a><i id='trash' class='fa fa-trash-o' ></i></a>"
            +"<a><i id='up' class='fa fa-arrow-circle-o-up disabledfornow' ></i></a>"
            +"<a><i id='down' class='fa fa-arrow-circle-o-down disabledfornow' ></i></a>"
            +"<a><i id='edit' class='fa fa-gear' ></i></a>"
            +"</li> </ul>" 
            + "</div>"
            + "</div>";

    containerCellObj.link = linkFnContainerCell;

    return containerCellObj;    
});

【问题讨论】:

  • 你能澄清一下你的问题吗?你的价值观是否因为它们在控制器中的变化而改变,这也反映在你的指令中?
  • @boroboris ...可能是的,但我只是使用 click event 更改特定单元格的范围。它应该更改相应的单元格,但它正在更改所有单元格,因为我正在更改范围。因此,我在询问如何进行范围更改,以便在发生单击事件时仅应用特定单元格。简单地说,我可以告诉我需要为特定单元格而不是整个单元格实现显示和隐藏。主要是单元格点击发生父指令和标签或输入(在单元格内)有子指令。请让我知道我需要更多说明。
  • 你能发布你的代码来创建一个点击事件吗?所以这个指令代表一个单元格?当您更改一个数据时,您希望该代码仅在该指令/单元格中更改,而不是在所有指令/单元格中?
  • @boroboris - 是的,正确...我已将点击事件代码放在底部。请看一看。
  • 我已经更新了答案。请看一下

标签: javascript angularjs


【解决方案1】:

经过一番思考,我认为解决该问题的最简单方法是向每个单元格添加新变量。我已经将我的命名为cellValue。之后,我们将模型值复制到该变量,并从现在开始从该变量中读取它。 我添加了方法 copyOrClone,它只返回一个变量(javascript 通过值传递变量和通过引用传递对象)或对象副本,以防我们传递了对象。你可以阅读更多关于它的信息here

bosAppModule.directive('webFactoryCellControlLabel',function($compile, $timeout, webFactoryEvents){

var layoutTableCellControlLabelObj={};

linkFnTableCellControlLabel=function(scope, element, attributes, controllerCtrl) {
scope.labelData="";
scope.lblShow = true;

scope.hideLblEditing = function () {
  $timeout(function() {
  scope.labelCtrlEdit.lblCtrlEdit = false;
  scope.labelCtrlEdit.lblCtrlView = true;
}, 2000);

};
};

layoutTableCellControlLabelObj.scope={
controlId:'=',attributeId:'=',layoutData:'=',
pageObject:'=', cellId:'=',lblProperties: '=', 
attrModel: '=', labelCtrlEdit:'=', lblShow: '=', 
cellValue:'='}; // this is new. value of the cell independent of value change in other cell directives. we get cell value from this variable

linkFnTableCellControlLabel=function(scope, element, attributes, controllerCtrl) {

    // you need this to clone objects
    // copy or clone object function
    function copyOrClone(obj) {
        if (null == obj || "object" != typeof obj) return obj;
        var copy = obj.constructor();
        for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
        }
        return copy;
    }


    scope.labelData="";     
    scope.lblShow = true;
    scope.hideLblEditing = function () {
       $timeout(function() {                
           scope.labelCtrlEdit.lblCtrlEdit = false; 
            scope.labelCtrlEdit.lblCtrlView = true; 

        }, 2000);  // 2000ms delay   

    };

    // newly added variable to help in copying object passed trough directive
    var temporaryVariableOrObject = pageObject.collections.objectattribute.rowset[attrIndex].objectattributelabelname;
    scope.cellValue = copyOrClone(temporaryVariableOrObject);
};




layoutTableCellControlLabelObj.template = "<div cell-value='cellValue'"
        + "layout-data='layoutData' "
        + "page-object='pageObject' "
        + "label-ctrl-edit ='labelCtrlEdit'"            
        + "class='col-xs-12 col-sm-12 col-md-6 col-lg-6' "
        + "style='padding-right:0px;padding-left:0px;padding-top: 0;' "             
        + ">" 
        + "<label ng-show='labelCtrlEdit.lblCtrlView' class='k-label pull-right control-label' style='padding-top: 8px'><div><span style='{{setLabelStyle()}}'>{{labelData}}</span> &nbsp;  : &nbsp; &nbsp; </div></label>"
        + "<div ng-if='cellId == labelCtrlEdit.inputShow'>"
        +" <input focus-on='labelCtrlEdit.lblCtrlEdit'  ng-show='labelCtrlEdit.lblCtrlEdit' type='text' ng-mouseleave='hideLblEditing()' style='margin-right: 10px' class='k-textbox pull-right' ng-model='cellValue'/> "   // changed model to cellValue
        +"</div>"

【讨论】:

  • 其实这不是我的要求
  • 我只是使用 click event 更改特定单元格的范围。它应该更改相应的单元格,但它正在更改所有单元格,因为我正在更改范围。因此,我在询问如何进行范围更改,以便在发生单击事件时仅应用特定单元格。简单地说,我可以告诉我需要为特定单元格而不是整个单元格实现显示和隐藏。主要是单元格点击发生父指令和标签或输入(在单元格内)有子指令。请让我知道我需要更多说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多