首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将异步获取的数据传递给指令

将异步获取的数据传递给指令
EN

Stack Overflow用户
提问于 2019-05-13 07:24:45
回答 2查看 0关注 0票数 0

我目前有一个AngularJS controller,基本上JSON通过$http.get()调用异步获取一些,然后将获得的数据链接到一些范围变量。

controller代码的恢复版本:

代码语言:javascript
复制
mapsControllers.controller('interactionsController', ['$http', function($http) {
  var ctrlModel = this;

  $http.get("data/interactionsPages.json").
  success(function(data) {
    ctrlModel.sidebar = {};
    ctrlModel.sidebar.pages = data;
  }).
  error(function() {...});
}]);

然后,我有一个自定义directive,通过HTML元素接收相同的范围变量。

directive代码的恢复版本:

代码语言:javascript
复制
mapsDirectives.directive('sidebar', function() {
  return {
    restrict : 'E',
    scope : {
      pages : '@'
    },
    controller : function($scope) {            
      $scope.firstPage = 0;

      $scope.lastPage = $scope.pages.length - 1;

      $scope.activePage = 0;

      //...
    },
    link : function(scope) {
      console.log(scope.pages);
    },
    templateURL : 'sidebar.html'
  }
});

恢复版的HTML

代码语言:javascript
复制
<body>
  <div ng-controller='interactionsController as interactionsCtrl'>
    <mm-sidebar pages='{{interactionsCtrl.ctrlModel.sidebar.pages}}'>
    </mm-sidebar>
  </div>
</body>

问题是,由于它$http.get()是异步的,因此指令被初始化很严重(例如:$scope.pages.length - 1未定义)。

我找不到任何可以解决这个问题的方法,尽管有一些解决方案似乎可以解决这个问题。也就是说,我试图观察变量,只在检测到变化后初始化变量,正如许多其他帖子所建议的那样。为了测试,我使用了类似的东西:

代码语言:javascript
复制
//... inside the directive's return{ }
link: function() {
  scope.$watch('pages', function(pages){
    if(pages)
      console.log(pages);
  });
}

我已经测试了它,并且$ watch函数没有多次被调用(记录的值是undefined),我认为这意味着它没有检测到变量值的变化。但是,我确认价值正在改变。

那么,这里的问题是什么?

EN

回答 2

Stack Overflow用户

发布于 2019-05-13 15:45:15

移动sidebar控制器中对象的声明并将范围绑定更改为=

代码语言:javascript
复制
mapsDirectives.controller("interactionsController", ["$http", "$timeout",
    function($http, $timeout) {
        var ctrlModel = this;
        ctrlModel.sidebar = {
            pages: []
        };
      /*
      $http.get("data/interactionsPages.json").
          success(function(data) {
          //ctrlModel.sidebar = {};
          ctrlModel.sidebar.pages = data;
       }).
       error(function() {});
      */

      $timeout(function() {
        //ctrlModel.sidebar = {};
        ctrlModel.sidebar.pages = ["one", "two"];
      }, 2000);
    }
]);

mapsDirectives.directive('mmSidebar', [function() {
    return {
      restrict: 'E',
      scope: {
        pages: '='
      },
      controller: function() {},
      link: function(scope, element, attrs, ctrl) {
        scope.$watch("pages", function(val) {
          scope.firstPage = 0;
          scope.lastPage = scope.pages.length - 1;
          scope.activePage = 0;
        });
      },
      templateUrl: 'sidebar.html'
    };
}]);

然后匹配指令名称并删除大括号。

代码语言:javascript
复制
<mm-sidebar pages='interactionsCtrl.sidebar.pages'>
</mm-sidebar>

这是一个有效的例子:http//plnkr.co/edit/VP79w4vL5xiifEWqAUGI

票数 0
EN

Stack Overflow用户

发布于 2019-05-13 16:49:01

问题似乎是你的HTML标记。

在您的控制器中,您指定了ctrlModel等于this

在您的html标记中,您声明了相同的this名称interactionsController。 因此,套结对ctrlModel,以interactionsController不正确。

代码语言:javascript
复制
<body>
  <div ng-controller='interactionsController as interactionsCtrl'>
    <!-- remove this -->
    <mm-sidebar pages='{{interactionsCtrl.ctrlModel.sidebar.pages}}'>

    <!-- replace with this -->
    <mm-sidebar pages='{{interactionsCtrl.sidebar.pages}}'>

    </mm-sidebar>
  </div>
</body>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100006718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档