2017-03-08 40 views
1

我一直在關注一些online tutorials並使用angularjs-template開始使用Angular。我無法使用控制器來更新頁面(html模板)。我認爲我設置控制器的方式存在問題,因爲這些值不適用於html模板。

我一直在嘗試遵循一些最好的practive指南,這些指南建議將我的組件包裝在「調用函數表達式」中,並分離出控制器,服務和服務管理器。不過,我想我已經做了一些散列,需要一些幫助來弄清楚我做錯了什麼。

使用控制檯我可以看到$ scope.metric包含我想要的信息。對我來說,這意味着控制器已經成功地通過metricService從我的API中取回數據。不過,我似乎無法將結果打印回html頁面,例如metric.id。

任何幫助表示讚賞 - 我在我的智慧嘗試弄清楚這一點的結尾。

metric.html

<div class="panel panel-primary"> 
<div class="panel-body"> 
    <!-- Try First Way to Print Results --> 
    Id: <span ng-bind="metric.id"></span></br> 
    Name:<input type="text" ng-model="metric.metadata.name" /></br> 

    <!-- Try Second Way to Print Results --> 
    <p data-ng-repeat="thing in ::MEC.metric track by $index"> 
     {{$index + 1}}. <span>{{thing.metadata.name}}</span> 
      <span class="glyphicon glyphicon-info-sign"></span> 
     </a> 
    </p> 

<!-- Try Third Way to Print Results --> 
    Id: <span ng-bind="Metric.metricId"></span></br> 
    Id: <span ng-bind="Metric.id"></span></br> 
    Id: <span ng-bind="metricService.id"></span></br> 

<!-- Try Fourth Way to Print Results --> 
     Id: <strong>{{::MEC.metric.id}}</strong></br> 
     Name: <strong>{{::MEC.metric.metadata.name}}</strong></br> 
     Height: <strong>{{::MEC.metric.type}}</strong> 
</div> 

metricController.js

(function() { 
    'use strict'; 

    angular.module('app.metric', ['app.metricService', 'app.metricManager'])  
     .controller('MetricController', MetricController) 

     MetricController.$inject = ['$scope', 'metricManager', '$log']; 

     function MetricController($scope, metricManager, $log) { 

      metricManager.getMetric(0).then(function(metric) { 
       $scope.metric = metric 
       $log.info('$scope.metric printed to console below:'); 
       $log.info($scope.metric); 
      }) 
     } 
})(); 

metricService.js

(function() { 
    'use strict'; 

    angular.module('app.metricService', [])  

    .factory('Metric', ['$http', '$log', function($http, $log) { 
     function Metric(metricData) { 
      if (metricData) { 
       this.setData(metricData); 
      } 
      // Some other initializations related to book 
     }; 

     Metric.prototype = { 
      setData: function(metricData) { 
       angular.extend(this, metricData); 
      }, 

      delete: function() { 
       $http.delete('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId); 
      }, 

      update: function() { 
       $http.put('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId, this); 
      }, 

      hasMetadata: function() { 
       if (!this.metric.metadata || this.metric.metadata.length === 0) { 
        return false; 
       } 
       return this.metric.metadata.some(function(metadata) { 
        return true 
       }); 
      } 
     }; 
     return Metric; 
    }]); 

})(); 

metricManager.js

(function() { 
    'use strict'; 

    angular.module('app.metricManager', []) 

    .factory('metricManager', ['$http', '$q', 'Metric', function($http, $q, Metric) { 
    var metricManager = { 
     _pool: {}, 
     _retrieveInstance: function(metricId, metricData) { 
      var instance = this._pool[metricId]; 

      if (instance) { 
       instance.setData(metricData); 
      } else { 
       instance = new Metric(metricData); 
       this._pool[metricId] = instance; 
      } 

      return instance; 
     }, 
     _search: function(metricId) { 
      return this._pool[metricId]; 
     }, 
     _load: function(metricId, deferred) { 
      var scope = this; 

      $http.get('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId).then(successCallback, errorCallback) 

       function successCallback(metricData){ 
        //success code 
        var metric = scope._retrieveInstance(metricData.id, metricData); 
        deferred.resolve(metric); 
       }; 

       function errorCallback(error){ 
        //error code 
        deferred.reject(); 
       } 
     }, 

     /* Public Methods */ 
     /* Use this function in order to get a metric instance by it's id */ 
     getMetric: function(metricId) { 
      var deferred = $q.defer(); 
      var metric = this._search(metricId); 
      if (metric) { 
       deferred.resolve(metric); 
      } else { 
       this._load(metricId, deferred); 
      } 
      return deferred.promise; 
     }, 

     /* Use this function in order to get instances of all the metrics */ 
     loadAllMetrics: function() { 
      var deferred = $q.defer(); 
      var scope = this; 
      $http.get('ourserver/books') 
       .success(function(metricsArray) { 
        var metrics = []; 
        metricsArray.forEach(function(metricData) { 
         var metric = scope._retrieveInstance(metricData.id, metricData); 
         metrics.push(metric); 
        }); 

        deferred.resolve(metrics); 
       }) 
       .error(function() { 
        deferred.reject(); 
       }); 
      return deferred.promise; 
     }, 

     /* This function is useful when we got somehow the metric data and we wish to store it or update the pool and get a metric instance in return */ 
     setMetric: function(metricData) { 
      var scope = this; 
      var metric = this._search(metricData.id); 
      if (metric) { 
       metric.setData(metricData); 
      } else { 
       metric = scope._retrieveInstance(metricData); 
      } 
      return metric; 
     }, 

    }; 
    return metricManager; 
}]); 
})(); 

段從App.routes

.state('root.metric', { 
        url: 'metric', 
        data: { 
         title: 'Metric', 
         breadcrumb: 'Metric' 
        }, 
        views: { 
         '[email protected]': { 
          templateUrl: 'core/features/metric/metric.html', 
          controller: 'MetricController', 
          controllerAs: 'MEC' 
         } 
        } 
       }) 

控制檯 enter image description here

+0

什麼是MEC在':: MEC.metric軌道由$指數「' –

+0

嘗試'{{::指標}}',看看你是否可以顯示基質對象 –

+0

能否請你展示我們在html中的ng-controller或加載控制器的代碼部分(路由或其他)。 –

回答

0

你混合兩個概念續滾動別名和$範圍,在你的情況下,你使用controllerAs創建控制器別名爲MEC。如果您使用的控制器別名,那麼這將正常工作對您:

function MetricController($scope, metricManager, $log) { 
    var MEC = this; 
    metricManager.getMetric(0).then(function(metric) { 
     MEC.metric = metric 
     $log.info('$scope.metric printed to console below:'); 
     $log.info($scope.metric); 
    }) 
} 

如果你不想通過$範圍使用控制器的別名和共享視圖和控制器之間的數據,那麼在你看來,你應該使用類似這個{{:: metric.metadata.name}}和控制器函數應該保持原樣。 PS:如果您使用別名,那麼MEC在var MEC = this可以是MEC或ABC或任何你喜歡的名字,但約定是使用var vm = thiscontrollerAs: 'vm'。如果你有controllerAs:'xyz',那麼在你的視圖xyz應該用來訪問模型。

+0

非常感謝 - 現在這個工作非常棒。使用Alias是推薦的做法還是應該使用$ scope在我的App.routes中沒有別名。 – n4nite

+0

別名是推薦的方法,如果它的工作然後pl輕鬆接受回答 –

0

您的視圖HTML存在問題,您需要在綁定時使用適當的Angular表達式。當你想使用:: MEC別名時,你需要用as keyowrd標記你的控制器,如ng-controller="xyz as MEC"。和結算工作Plunker

<div class="panel panel-primary"> 
    <div class="panel-body"> 
     <!-- Try First Way to Print Results --> 
     Id: <span ng-bind="metric.id"></span> 
     <br> Name1: 
     <input type="text" ng-model="metric.metadata.name" /> 
     <br><br><br><br> 

     <!-- Try Second Way to Print Results --> 
     <p data-ng-repeat="thing in [metric] track by $index"> 
     {{$index + 1}}. <span>{{thing.metadata.name}}</span> 
     <span class="glyphicon glyphicon-info-sign"></span> 

     </p><br><br><br> 

     <!-- Try Third Way to Print Results --> 
     Id: <span ng-bind="metric.metricId"></span> 
     <br> Id: <span ng-bind="metric.id"></span> 
     <br><br><br> 

     <!-- Try Fourth Way to Print Results --> 
     Id: <strong>{{::metric.id}}</strong> 
     <br> Name: <strong>{{::metric.metadata.name}}</strong> 
     <br> Height: <strong>{{::metric.type}}</strong> 
    </div> 
    </div> 
+0

感謝您的四點建議。來自@ɢʜʘʂʈʀɛɔsolution的解決方案解決了我的問題,但接下來我會更詳細地介紹一下您的運動員。 – n4nite

相關問題