Angular $ scope在HTML模板中不可用,但我可以在控制台日志中看到它?

时间:2017-03-08 19:18:24

标签: javascript angularjs angularjs-scope

我一直关注一些online tutorials并使用angularjs-template开始使用Angular。我无法使用控制器更新页面(html模板)。我认为我设置控制器的方式存在问题,因为html模板无法使用这些值。

我一直在尝试遵循一些最好的实践指南,这些指南建议将我的组件包装在“调用的函数表达式”中,并分离出控制器,服务和服务管理器。但是,我想我已经对此做了一些讨论,需要一些帮助来弄清楚我做错了什么。

使用控制台我可以看到$ 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: {
                        'content@': {
                            templateUrl: 'core/features/metric/metric.html',
                            controller: 'MetricController',
                            controllerAs: 'MEC'
                        }
                    }
                })

控制台 enter image description here

2 个答案:

答案 0 :(得分:0)

您正在混合两个概念控制器别名和$ scope,在您使用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);
    })
}

如果您不想使用控制器别名并通过$ scope在视图和控制器之间共享数据,那么在您的视图中,您应该使用类似此{{:: metric.metadata.name}}的内容,并且控制器功能应保持为它是。

PS:如果您使用别名,则var MEC = this中的MEC可以是MEC或abc或您喜欢的任何名称,但约定是使用var vm = thiscontrollerAs: 'vm'。如果您有controllerAs:'xyz',那么您应该使用xyz来访问模型。

答案 1 :(得分: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>