2017-03-09 33 views
0

我有一個使用d3顯示項目的角度應用程序,並且有一個顯示被點擊項目信息的infoPanel。這是工作,但點擊該項目來激活/打開infopanel不起作用。

在D3數據控制文件,我有:

'use strict'; 

var settings ; 


angular.module('App') 
    .directive('data', ['sessionmgmt', 'thedata', 'gui', function (session, data, gui) { 
     return { 
      link: function postLink(scope, element, attrs) { 

       var promise = angular....getData...; 
       promise.then(function() { 

        settings = session.settings; 

        svg = ... 

        createItems(svg, items); 
       }, function() {}); 
      } 
     }; 
    }]); 

function createItems(svg, items) { 


    let item = svg.append("g") 
     .attr("class", "nodes") 
     .selectAll(".node") 
     .data(items, function (d) { 
      return d.id; 
     }); 


    appendIcons(item); 

} 

function appendIcons(nodes){ 
    nodes = nodes.enter().append("g") 
    .attr("class", "node"); 

    nodes.append("title") 
     .text(function (d) { 
      return d.data['label']; 
     }); 

    nodes.on("click",function(d){ 
    if(settings.selectedItem === d.id){ 
     settings.selectedItem = null; 
    }else{ 
     settings.selectedItem = d.id; 
    } 

    }); 

} 

然後在我的信息面板控制器我有:

'use strict'; 

angular.module('App') 
    .controller('ContentpanelCtrl', ['$scope', 'sessionmgmt', function ($scope, sessionmgmt) { 
    var contentPanel = this; 

    this.settings = sessionmgmt.settings; 

    $scope.activate = function activate() { 
     contentPanel.settings.contentPanelOpen = true; 
    }; 


    $scope.getSelected = function getSelected(){ 
     return contentPanel.settings.itemSelected; 
    } 

    $scope.isNodeSelected = function isSelected(){ 
     return contentPanel.settings.itemSelected !== null; 
    } 

    $scope.$watch("contentPanel.settings.itemSelected", function(newVal, oldVal) { 
     console.log(newVal); 
     if (newVal !== oldVal){ 
     $scope.activate(); 
     } 
    }); 


    }]); 

的執行console.log運行時,第一次加載頁面,但那麼當我點擊物品時,這隻手錶並未被解僱。 我知道'click'正在工作,因爲getSelected正在我的infopanel上顯示正確的數據。 '手錶'和getSelected都使用完全相同的設置變量....難住。

+0

添加點擊功能在您的控制器,並添加'NG-click'in你對一個項目的HTML指向該功能。我不認爲在你使用jQuery以外的情況下,angular會發現這種變化。 – Arg0n

+1

您是否嘗試將範圍傳遞給'createItems'然後'appendIcons'函數並在點擊事件後調用'scope。$ apply()'? – Razzildinho

+0

@Razzildinho - 那真是太棒了!謝謝。我仍然沒有使用$ watch函數,但是不需要,因爲我的click函數現在運行'contentPanel.settings.contentPanelOpen = true;'和scope。$ apply使它可見。 –

回答

1

這樣做有兩種方式。第一個是我在註釋中被取消的地方,在該註釋中,您將指令的範圍作爲參數傳遞到點擊事件中調用scope.$apply();createItemsappendIcons函數。

從指令:

createItems(svg, items, scope); 

而其他功能:

function createItems(svg, items, scope) { 

    let item = svg.append("g") 
     /* ... */ 

    appendIcons(item, scope); 

} 

function appendIcons(nodes, scope){ 
    nodes = nodes.enter().append("g") 
     /* ... */ 

    nodes.on("click",function(d){ 
     if(settings.selectedItem === d.id){ 
      settings.selectedItem = null; 
     }else{ 
      settings.selectedItem = d.id; 
     } 
     scope.$apply(); 
    }); 

} 

另一種方式是改變你的$scope.$watch()功能。您要注意的contentPanel.settings.itemSelected不屬於範圍的一部分,因爲您使用的是this而不是$scope,我假定它是controllerAs的一部分。爲了拿到手錶工作,你需要使用一個函數作爲第一個參數的監視功能如下所示:

$scope.$watch(function(){ 
    return contentPanel.settings.itemSelected; 
}, function(newVal, oldVal) { 
    if (newVal !== oldVal){ 
     $scope.activate(); 
    } 
}); 
0

也許你可以嘗試將確切的對象傳遞給觀察者而不是字符串?

$scope.$watch(function() { 
    if (contentPanel && contentPanel.settings) { 
    return contentPanel.settings.itemSelected; 
    } 
}, function(newVal, oldVal) { 
    console.log(newVal); 
    if (newVal !== oldVal){ 
    $scope.activate(); 
    } 
}); 
+0

感謝您的建議。你推薦的第一個功能無法訪問contentPanel ...我把console.log(contentPanel.graphSettings);在那個函數中,它輸出未定義的。 –

+0

@FrazerKirkman從您的更新代碼判斷,此功能應該工作,爲了安全我已更新爲空檢查 – Icycool

+0

我不確定你的意思:( –

0

作爲我評論的補充。

在控制器:

$scope.toggleSelectedItem = function(item) { 
    if(contentPanel.settings.itemSelected && 
     contentPanel.settings.itemSelected === item.id){ 
    contentPanel.settings.itemSelected = null; 
    } 
    else { 
    contentPanel.settings.itemSelected = item.id; 
    } 
} 

HTML:

<div ng-repeat="item in items" ng-click="toggleSelectedItem(item)"> 
    <!--Content--> 
</div> 
+0

謝謝。我的點擊功能是在數據控制指令文件中定義的。點擊功能無法訪問$ scope變量 –

+0

您可以發佈整個指令嗎? – Arg0n

+0

我現在在我的問題中包含了大部分指令文件。 –