【问题标题】:AngularJS - How to run controllers from other controllers?AngularJS - 如何从其他控制器运行控制器?
【发布时间】:2013-04-30 14:12:17
【问题描述】:

我是 Angular 的新手,来自 jquery 的思维方式。我已经阅读了大部分主要网站和其他一些内容,并且正在尝试通过构建可自定义的仪表板应用程序来进一步学习。

我的 HTML:

    <div class="library">
        <div class="dropdown" ng-controller="LibraryCtrl">
            <div id="lib-{{widget.WidgetID}}" ng-repeat="widget in widgets">
                <div data-toggle="tooltip" title="{{widget.WidgetDesc}}">
                    <h2>
                        {{widget.WidgetName}}</h2>
                    <div class="libraryWidget {{widget.WidgetReportType}}">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="dashboard" ng-controller="DashboardCtrl">
        <div>
            <article>
                <div id="dash-{{widget.WidgetID}}" class="jarviswidget" ng-repeat="widget in widgets">
                    <header role="heading">
                        <h2>
                            {{widget.WidgetName}}</h2>
                    </header>
                    <div role="content" class="content">
                        <div class="inner-spacer">
                            <div class="table">
                            </div>
                        </div>
                    </div>
                </div>
            </article>
        </div>
    </div>

基本上,我正在为可用小部件的“库”构建一个视图,并为当前为其“仪表板”选择的小部件构建另一个视图。 HTML 在这里仍然很简单。库视图渲染得很好,但仪表板视图却不行。

JavaScript:

function LibraryCtrl($scope, $http, sharedModels) {
    $http({
        method: 'POST',
        url: '../Services/GetUserWidgetDetails',
        headers: {
            'Content-type': 'application/json'
        }
    }).success(function (data) {
        sharedModels.setProperty(data);
        $scope.widgets = data;
        console.log(data); // logs 2nd with expected data
    });
}

function DashboardCtrl($scope, sharedModels) {
    var libraryWidgets = sharedModels.getProperty();
    $scope.widgets = libraryWidgets;
    console.log(libraryWidgets); // logs 1st with empty object
}

angular.module('dashboard', [])
    .service('sharedModels', function () {
        var libraryModel = {};

        return {
            getProperty: function () {
                return libraryModel;
            },
            setProperty: function (data) {
                libraryModel = data;
            }
        };
    });

我的两个控制器都应该使用相同的模型,所以在其他 SO 帖子的建议下,我创建了服务来获取和设置这个共享模型。问题是,我的 DashboardCtrl 尝试在 LibraryCtrl 成功之前呈现其视图。 解决这个问题的角度方法是什么:让 DashboardCtrl 等待 LibraryCtrl 成功?

进一步,(这可能值得成为它自己的问题/帖子,)如果我的 div.dashboard 视图中的 div.content 元素将根据 LibraryCtrl 的成功 JSON 转到许多可能的子模板之一,怎么可能我去干这个?在 jquery 模板中,我将为每个模板设置 id,jquery 将呈现 HTML 并将其附加到需要的地方。在角度方面,我不确定如何选择一个模板并在另一个模板中渲染。这不需要像我上面的第一个粗体问题那样为我详细说明,但是朝着正确方向的一点会很棒!

【问题讨论】:

    标签: javascript jquery ajax model-view-controller angularjs


    【解决方案1】:

    第一个问题:不要在LibraryCtrl 中加载数据并在DashboardCtrl 中使用它,而是创建一个服务。通过服务加载模型并让两个控制器都使用它。

    http://docs.angularjs.org/api/ngResource.$resource

    如果您还没有看过angular-seed,请看一看。它为这类事情提供了一个很好的骨架。

    关于你的第二个问题:这是指令的理想场所。 (大量 Angular 问题的答案是“制定指令”,如果您正在制作可重用的小部件,那就更是如此)。事实上,我会为整个仪表板做一个指令,另一个用于“仪表板项目”。与其在指令声明中直接指定模板,不如使用 templateUrl...,它可以使用表达式的结果。根据类型将其指向不同的模板文件。

    或者,创建一个模板文件并根据类型使用ng-switch 来确定要显示的部分。

    有关创建指令的信息,请查看教程并查看here

    跳至“编写指令(长版)”。不要阅读编译和链接的东西;如果需要,请返回它。内容在该页面上的显示顺序很糟糕。

    【讨论】:

      【解决方案2】:

      将数据的加载移动到服务中,然后在两个控制器中使用服务:

      http://jsfiddle.net/ADukg/2631/

      var myApp = angular.module('myApp',[]);
      
      function LibraryCtrl($scope, sharedModels) {
          $scope.widgets = sharedModels;
      }
      
      function DashboardCtrl($scope, sharedModels) {
          $scope.widgets = sharedModels;
          sharedModels.then(function (x) {
              console.log(x); 
          });
      }
      
      myApp.factory('sharedModels', function($q,$timeout) {
          /*
          return $http({
              method: 'POST',
              url: '../Services/GetUserWidgetDetails',
              headers: {
                  'Content-type': 'application/json'
              }
          })*/
          // Simulate http request.
          var data = $q.defer();    
          $timeout(function() {
              data.resolve([{WidgetName:'Sproket'}, {WidgetName:'Dohickey'}])
          }, 2000);
          return data.promise;
      });
      

      【讨论】:

        猜你喜欢
        • 2015-06-17
        • 2016-11-25
        • 2019-04-01
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多