Angular:使用从指令传递到控制器的值来更新视图

时间:2017-03-28 22:52:23

标签: javascript angularjs angularjs-directive angularjs-controller highmaps

萌芽的网络开发者在这里努力从我的控制器更新视图。

我使用highmaps和angular为我的网络应用程序构建了一个整洁的选择工具。我有一个嵌套在控制器范围内的指令。我希望此指令更新存储在控制器中的值(selectedCountry)。然后,我希望控制器在视图上显示最新的selectedCountry值。

我检查过该指令是否将正确的selectedCountry值传递给父控制器。但是,控制器不会更新视图以匹配更新的值。如果有人能看一眼,我将不胜感激。

在此演示:http://jsfiddle.net/frauLLmr/5/

index.html

<div ng-app="myApp">
  <div ng-controller="GraphController as graphCtrl">
    <div> {{graphCtrl.showSelectedCountry()}} </div>
    <div> {{graphCtrl.selectedCountry}} </div>
    <high-chart-directive update-selected-country='graphCtrl.updateSelectedCountry(newCountry)'></high-chart-directive>
  </div>
</div>


app.js

var myApp = angular.module('myApp', []);
myApp.controller('GraphController', function() {
  var self = this;
  self.selectedCountry = 'unselected';
  var outsideScopeTest = function() {
    alert('selectedCountry (from controller scope): ' 
        + self.selectedCountry);
  };
  self.updateSelectedCountry = function(newCountry) {
    self.selectedCountry = newCountry;
    outsideScopeTest();
  };
  self.showSelectedCountry = function() {
    return self.selectedCountry;
  };
});

myApp.directive('highChartDirective', function () {
  return {
    restrict: 'E',
    scope: {
      updateSelectedCountry: '&'
    },
    link: function(scope, element) {
      Highcharts.mapChart(element[0], getMapOptions(mapClick));

      function mapClick(event) {
        scope.updateSelectedCountry({newCountry: event.point.name});
        alert('selectedCountry (from directive scope): ' 
        + event.point.name);
      }
    }
  };

  function getMapOptions(callback) {
    return {
      title: {
        text: ''
      },
      mapNavigation: {
        enabled: true,
        buttonOptions: {
          verticalAlign: 'bottom'
        }
      },
      series: [{
        data: getTestCountries(),
        mapData: Highcharts.maps['custom/world-highres'],
        // TODO-chantelle: figure out how geoJSON joinBy works
        joinBy: 'hc-key',
        name: 'Emission per capita',
        states: {
          hover: {
            color: '#9370DB'
          }
        },
        dataLabels: {
          enabled: false,
          format: '{point.name}'
        }
      }],
      plotOptions: {
        series: {
          events: {
            click: function(event) {
              callback(event);
            }
          }
        }
      }
    };
  }

  function getTestCountries() {
    return [{
      "hc-key": "ca",
      "value": 0
    }, {
      "hc-key": "br",
      "value": 1
    }, {
      "hc-key": "ru",
      "value": 2
    }];
  }
});

2 个答案:

答案 0 :(得分:0)

问题是Highcharts.mapChart(element [0],getMapOptions(mapClick));不是角度范围的一部分。因此,此处的任何调用都不会触发角度应用程序刷新。您需要使用$ scope.apply();

强制更新角度
export const generateNavigator = (screens, navigatorConfig) => 
  StackNavigator(screens, navigatorConfig);

const NavigatorView = (myArg, props) => {
    const Navigator = generateNavigator(screens, myArg);
    return (<Navigator screenProps={{ ...props }}/>);
};

答案 1 :(得分:0)

试试这个

<div ng-app="myApp">
  <div ng-controller="GraphController as graphCtrl">
    <div> {{graphCtrl.showSelectedCountry()}} </div>
    <div> {{graphCtrl.selectedCountry}} </div>
    <high-chart-directive update-selected-country='graphCtrl.updateSelectedCountry(newCountry)'></high-chart-directive>
  </div>
</div>

js

var myApp = angular.module('myApp', []);
myApp.controller('GraphController', function($scope) {
  var self = this;
  self.selectedCountry = 'unselected';
  var outsideScopeTest = function() {
    alert('selectedCountry (from controller scope): ' 
        + self.selectedCountry);
      $scope.$apply();
  };
  self.updateSelectedCountry = function(newCountry) {
    self.selectedCountry = newCountry;
    outsideScopeTest();
  };
  self.showSelectedCountry = function() {
    return self.selectedCountry;
  };
});

myApp.directive('highChartDirective', function () {
  return {
    restrict: 'E',
    scope: {
      updateSelectedCountry: '&'
    },
    link: function(scope, element) {
      Highcharts.mapChart(element[0], getMapOptions(mapClick));

      function mapClick(event) {
        scope.updateSelectedCountry({newCountry: event.point.name});
        alert('selectedCountry (from directive scope): ' 
        + event.point.name);
      }
    }
  };

  function getMapOptions(callback) {
    return {
      title: {
        text: ''
      },
      mapNavigation: {
        enabled: true,
        buttonOptions: {
          verticalAlign: 'bottom'
        }
      },
      series: [{
        data: getTestCountries(),
        mapData: Highcharts.maps['custom/world-highres'],
        // TODO-chantelle: figure out how geoJSON joinBy works
        joinBy: 'hc-key',
        name: 'Emission per capita',
        states: {
          hover: {
            color: '#9370DB'
          }
        },
        dataLabels: {
          enabled: false,
          format: '{point.name}'
        }
      }],
      plotOptions: {
        series: {
          events: {
            click: function(event) {
              callback(event);
            }
          }
        }
      }
    };
  }

  function getTestCountries() {
    return [{
      "hc-key": "ca",
      "value": 0
    }, {
      "hc-key": "br",
      "value": 1
    }, {
      "hc-key": "ru",
      "value": 2
    }];
  }
});