如何在承诺中指定范围?

时间:2014-07-28 00:07:26

标签: angularjs scope angularjs-scope

我想在我的范围内将一个值分配到一个promise(在http.get中)但我的值并没有分配给我的范围!我尝试了很多东西(在我的控制器中使用$ scope而不是this.scope),但它不起作用:(

这是我的HTML搜索输入:

<input class="searchContent" type="text" placeholder="Type here to search content" ng-controller="searchCtrl as search" ng-keyup="search.typingQuery()" ng-model="search.scope.url">

以下是我对搜索页面的看法:

<div class="bodyContent" ng-controller="searchCtrl as search">

<div class="icon-category categorySearch"></div>
<div class="categoryBar"></div>

{{ search.scope.results }}

这是我的JS代码:

( function()
{

var app;

app = angular.module( 'searchModule', [] );

app.controller( 'searchCtrl', ['$location', '$http', function($location, $http)
{

    var This = this;

    this.typingQuery = function()
    {

        var url = This.scope.url;

        if ( url != '' && url != undefined )
        {
            if ( url == 'profile' || url == 'education' || url == 'skills' || url == 'experience' || url == 'contact' )
                $location.path( url );
            else
            {
                $location.path( 'search/' + url );
                $http.get( '/json/profile.json' )
                    .success( function(data)
                    {
                        var re = new RegExp(url);
                        var results = data.sections[0].body.match( re );

                        This.scope.results = results;
                    } )
                    .error( console.log( 'Error: failed to load json' ) );
            }
        }
        else
            $location.path( 'profile' );

    };

} ] );

} )();

提前谢谢!

2 个答案:

答案 0 :(得分:0)

在Angular-land中,你不能使用&#34;这个&#34;非常(这是一种解脱,因为它可以节省不得不像#34;这样&#34;或者&#34;自我&#34;在许多情况下像我们以前一直习惯的那样)。< / p>

相反,您可以将数据分配给控制器的范围,并始终对此有一个很好的参考。但你必须通过要求获得参考。如果你不这样做,$ scope肯定不会是你认为的那样。当你尝试将一些东西放入其中时(或根据你所做的事情抛出异常),你最终会遇到经典的JS错误,即创建一个全局变量。

您必须要求Angular将$ scope注入您的控制器,以便您可以使用它:

app.controller( 'searchCtrl', ['$scope', '$location', '$http', function($scope, $location, $http) {
    // Now you can safely/correctly use $scope.XYZ here. Note that you typically define
    // both data and functions here:
    $scope.results = '';

    $scope.typingQuery = function() {
        // ...
    }

    // ...
}

在您的模板中,您可以将它们简化为:

<input class="searchContent" ... ng-keyup="typingQuery()" ng-model="url">

请注意,您通常也不会使用as关键字以您的方式访问控制器 - 它可以完成,但它会很快混淆并且很难调试。您通常在外部DIV图层中包含类似搜索块的内容。当你这样做时,内心的任何东西都不再需要这个黑客:

<div class="search-box" ng-controller="searchCtrl">
    <!-- Search input boxes, outputs, buttons, etc. here -->
    <input class="searchContent" type="text" placeholder="Type here to search content" ng-keyup="typingQuery()" ng-model="url">
</div>

它基本相同,但让您输入的内容少一些(只要您的搜索组件靠得很近)。

答案 1 :(得分:0)

我找到了答案,现在我使用$ scope和一个工厂来总是在我的所有示波器上都有我的数据,真正的双向数据绑定;)

这是我的json工厂(将我的.json存储在app模块中,以便我的数据无处不在):

app.factory( 'jsonFactory', ['$http', '$q', function($http, $q)
{
    var factory = {

        jsonData: null,
        jsonFile: function()
        {
            var deferred = $q.defer();

            $http( {method: 'GET', url: '/json/data.json', cache: true} )
                .success( function(data)
                {
                    factory.jsonData = data;
                    deferred.resolve( factory.jsonData );
                } )
                .error( function()
                {
                    deferred.reject( 'Error: failed to load json' );
                } );
            return deferred.promise;
        }
    };
    return factory;
} ] );

app.controller( 'jsonCtrl', ['$scope', 'jsonFactory', function($scope, jsonFactory)
{
    $scope.jsonData = jsonFactory.jsonFile().then(
        function(data) { $scope.jsonData = data; },
        function(error) { console.log( error ); } );
} ] );

我在我的身体上调用我的控制器jsonCtrl:

<body ng-controller="jsonCtrl">

    <div ng-view></div>

</body>

现在,我可以在这里的每个范围内访问我的数据:

app.controller( 'searchCtrl', ['$scope', '$location', 'jsonFactory', 'resultsFactory', function($scope, $location, jsonFactory, resultsFactory)
{
    $scope.search = {

        url: "",
        searchQuery: function()
        {
            if ( this.url == 'profile' || this.url == 'education' || this.url == 'skills' || this.url == 'experience' || this.url == 'contact' )
            {
                $location.path(this.url);
            }
            else if ( this.url != 'search' )
            {
                $location.path('search');
            }

            var re = new RegExp(this.url);

            resultsFactory.results = [];
            if ( this.url != '' )
            {
                jsonFactory.jsonData.profile.forEach( function(elt)
                {
                    var matched = elt.body.match(re);

                    if ( matched )
                        resultsFactory.results.push( matched );
                    console.log( resultsFactory.results );
                } );
            }
        },
        getResults: function()
        {
            return resultsFactory.results;
        }
    };
} ] );

我在儿童范围内获取数据的代码:

<div class="bodyContent" ng-controller="searchCtrl">

    ...

    <span ng-repeat="result in search.getResults()">
        {{ result.input }}
    </span>

</div>

所以,使用工厂和承诺,你永远不会有范围问题;)