2015-08-27 29 views
1

我在一個角度指令中包裝D3 svg圖像。當用戶點擊D3圖像時,我想在控制器中設置一個變量爲true,這樣ng-show會顯示另一個D3圖像。

我所做的是在D3圖像中添加.on("click")函數,並在該函數中使用$rootScope.$emit()發送事件。在第二個圖像的控制器中,我有一個$rootScope.$on()來附加事件,並將ng-show的變量設置爲true。

此方法不起作用。我已經測試了代碼以確保事件被排除並被正確捕獲,但是它是,但是ng-show不顯示第二個D3圖像。

這是爲什麼?

我已經創建了一個小plunkr來說明我正在嘗試做什麼。 http://plnkr.co/edit/FnqeAF9kVXxdUdOzT5to

控制器代碼如下:

function CircleCtrl($rootScope) { 

    this.render = function(element, attrs) { 
     var svg = d3.select(element[0]).append("svg") 
      .attr("width", 200) 
      .attr("height", 200); 

     var circle = svg.append("circle") 
      .attr("cx", 30) 
      .attr("cy", 30) 
      .attr("r", 20); 
     circle.on("click", function(d,i) { 
      var data = {val0: "zero", val1: "one"}; 
      $rootScope.$emit("Circle Clicked", data); 
     }); 
    }; 

} 

function SquareCtrl($rootScope) { 
    this.showSquare = false; 

    $rootScope.$on("Circle Clicked", function(event, data) { 
     this.showSquare = true; 
    }) 

    this.render = function(element, attrs) { 
     var svg = d3.select(element[0]).append("svg") 
      .attr("width", 200) 
      .attr("height", 200); 

     var rectangle = svg.append("rect") 
      .attr("x", 10) 
      .attr("y", 10) 
      .attr("width", 50) 
      .attr("height", 100); 
    }; 

    } 

    angular.module("AngularD3Example") 
     .controller("CircleCtrl", ["$rootScope", CircleCtrl]) 
     .controller("SquareCtrl", ["$rootScope", SquareCtrl]); 

回答

2

從外部角上下文改變的角度範圍將不會更新範圍的變量和結合,因爲它不會運行Angular.In的摘要週期此使用的是事件click到角上下文。

您需要運行$apply()方法,在一個作用域到$rootScope上運行digest循環纔會有效更新綁定。

代碼

circle.on("click", function(d,i) { 
    var data = {val0: "zero", val1: "one"}; 
    $rootScope.$emit("Circle Clicked", data); 
    $rootScope.$apply(); 
}); 

是你需要確保在與this關鍵字玩,你應該用一些變量聲明它之外,然後其他的事情,用它

控制器

function SquareCtrl($rootScope) { 
    var square = this; //made this as a global can be accessible through `square` variable 
    square.showSquare = false; //<-- as changed this to square 

    $rootScope.$on("Circle Clicked", function(event, data) { 
     square.showSquare = true; //<-- as changed this to square 
    }) 

    //.... 

} 

您還必須取消註冊ister $ rootScope偵聽器,否則會導致應用程序中的內存泄漏。的。對聽衆的返回值是實際使用時,$破壞爲了實現這一

// Start Custom Events 
var cleanApplyEvent = $rootScope.$on('submitChanges', function(event, args) { 
    self.applyData(args); 
}) 

// manually unregister rootScope listeners to avoid memory leaks 
$scope.$on('$destroy', function(){ 
    cleanApplyEvent(); 
}) 
// End Custom Events 

Working Plunkr

注意

它不好的做法,事件發生的函數要在控制器內部進行DOM操作,您應該創建一個指令並執行DOM操作,並且事件應該是 從那裏開始處理

+0

您還需要取消註冊$ rootScope偵聽器,否則會導致應用程序內存泄漏。 – Yeysides

+0

@Yeysides感謝您的編輯..讚賞它。我以某種方式對其進行了改進。 –

+0

感謝您接受...我犯了一些語法錯誤,但是由您來改變它們! – Yeysides