2017-01-16 38 views
0

我使用Angularjs組件和ES6構建一個也使用d3js的應用程序。我正在使用DOM操作的屬性指令。由於該組件具有我試圖在鏈接函數中訪問它的範圍,並在內部使用$ watch。我的疑問來自於我試圖觀察和訪問的變量在$ scope中。$ ctrl。在這種情況下訪問它們的正確方法是什麼?

模板

<div class="card"> 
    <svg network-svg> 
    </svg> 
</div> 

組件

export const NetworkComponent = { 

    template, 
    controller: class NetworkComponent { 

     constructor(CommService) { 
      'ngInject' 
      this.comm = CommService; 
      this.physicalTree = new NodeTree('physical'); 
      this.virtualTree = new NodeTree('virtual'); 
      this.pVisible = true; 
     } 
    } 
} 

指令 現行指令的代碼,但返回undefined。

export const NetworkSvg =() => { 

    return { 
     restrict: 'A', 
     link($scope, $element, $attrs) { 
      $scope.$watch('virtualTree', function() { 

      }); 

      $scope.$watch('physicalTree', function() { 

      }); 
    } 
} 

回答

0

$ctrl對象是範圍的屬性。簡單地使用在手錶:

export const NetworkSvg =() => { 

    return { 
     restrict: 'A', 
     link: ($scope, $element, $attrs) => { 
      //$scope.$watch('virtualTree', function() { 
      $scope.$watch('$ctrl.virtualTree', function(newValue) { 
       console.log(newValue);  
      }); 

      //$scope.$watch('physicalTree', function() { 
      $scope.$watch('$ctrl.physicalTree', function(newValue) { 
       console.log(newValue);  
      }); 
     } 
    } 
} 

在底層中,AngularJS框架使用controller as $ctrl當它實例化一個組件的控制器。控制器的this上下文設置爲組件範圍的$ctrl屬性。


So there's no harm in accessing it, in this case, with $scope.$ctrl.physicalTree ?

由於採用了耐用的設計問題,最好是避免硬連線模型變量名到自定義指令。相反,使用屬性來定義名稱:

export const NetworkSvg =() => { 

    return { 
     restrict: 'A', 
     link: (scope, element, attrs) => { 
      //scope.$watch('virtualTree', function() { 
      //scope.$watch('$ctrl.virtualTree', function() { 
      scope.$watch(attrs.virtualTree, function(newValue) { 
       console.log(newValue);  
      }); 

      //scope.$watch('physicalTree', function() { 
      //scope.$watch('$ctrl.physicalTree', function() { 
      scope.$watch(attrs.physicalTree, function(newValue) { 
       console.log(newValue); 
      }); 
     } 
    } 
} 

然後使用屬性來定義接線:

<my-component virtual-tree="$ctrl.virtualTree" 
       physical-tree="$ctrl.physicalTree" ></my-component> 

這也使得更versitile指令在佈線清晰。


I'm having a hard time with this solution since, as far as I've tried and read, doing this through attributes the values passed are just string literals. How would I pass objects though?

引擎蓋下,$watch使用scope.$eval評估角表達。其他的代碼可以使用它,以及:

例如:

<div my-event="$ctrl.handle($event)"></div> 

JS:

link: (scope,elem,attrs) => { 
    elem.on("someEvent", function(e) { 
     scope.$eval(attrs.myEvent({$event: e}); 
     scope.$apply(); 
    }); 
} 

欲瞭解更多信息,請參閱

+0

因此,在使用$ scope的情況下訪問它並沒有什麼壞處。$ ctrl.physicalTree? –

+0

查看我的答案更新。 – georgeawg

+0

非常感謝,那正是我對此的懷疑,似乎有點做作。但我看到屬性是要走的路。 –

0

我發現一個語法錯誤: 你能和這個替換指示的代碼...並嘗試

export const NetworkSvg =() => { 

    return { 
     restrict: 'A', 
     link: ($scope, $element, $attrs) => { 
      $scope.$watch('virtualTree',() => { 

      }); 

      $scope.$watch('physicalTree',() => { 

      }); 
    } 
} 
0

在我看來,就像如果你將屬性到它會更清楚你的指令顯然取決於他們。例如

<svg network-svg virtual-tree="virtualTree" physical-tree="physicalTree"> 

然後,你可以鏈接功能的$attrs屬性中訪問這些值,以及控制器上的範圍。

+0

可能是一個愚蠢的問題,但會與指令被用作屬性兼容嗎? –

+0

當你學習時,不會有這樣愚蠢的問題! ;)是的,它完全兼容。無論指令是使用元素名稱,屬性還是類名稱來定義,都可以用這種方式傳遞屬性。 – RobMasters