如何在AngularJS中的控制器之间传递数据?

时间:2014-10-03 14:48:40

标签: javascript angularjs

我需要保留两个独立的控制器,一个用于搜索区域,另一个用于显示数据。执行搜索时,我需要从Internet获取数据并使用新数据更新视图。我不想用更大的控制器或类似的东西包装所有东西(这是最好的做法吗?)但我更喜欢搜索和显示控制器保持完全分离。

这是相对于搜索字段和显示网格的HTML代码

<div id="mainContainer" class="container-fluid" >


    <div id="searchContainer">
        <div id="search" ng-controller="SearchController as srcCtrl">
            <!-- on submit call submit(title) -->
            <form class="navbar-form" role="search">
                <div class="input-group">
                    <input ng-model="title" type="text" class="form-control" placeholder="Search" name="srch-term" id="srch-term">
                    <div class="input-group-btn">
                        <button class="btn btn-default" ng-click="srcCtrl(title)"><i class="glyphicon glyphicon-search"></i></button>
                    </div>
                </div>
            </form>
        </div>

    </div>


    <div id="animeContainer" class="container-fluid">
        <div class="clearfix"></div>
        <!-- animeContainer directive -->
        <anime-container></anime-container>
    </div>


</div>

Angular代码:

(function(){
var app = angular.module('hummingbird', []);


app.controller('AnimeListController', function(){

    this.anime = animeList;     //list of anime to display in anime list

    this.onSelectAnime = function(anime){
        console.log(anime);
    };
});


app.controller('SearchController', function(){

    this.submit = function(srcstr){

        //here I call the API and then I want to update the anime variable in AnimeListController
        console.log(srcstr);
    }

});

app.directive("animeContainer", function(){
    return{
        restrict: 'E',
        templateUrl: 'anime-container.html',
    }
});

var animeList = [{"id":25,"slug":"ghost-in-the-shell","status":"Finished Airing","url":"https://hummingbird.me/anime/ghost-in-the-shell","title":"Ghost in the Shell","alternate_title":null,"episode_count":1,"cover_image":"https://static.hummingbird.me/anime/poster_images/000/000/025/large/25.jpg?1408440508","synopsis":"In the year 2029, the barriers of our world have been broken down by the net and by cybernetics, but this brings new vulnerability to humans in the form of brain-hacking. When a highly-wanted hacker known as 'The Puppetmaster' begins involving them in politics, Section 9, a group of cybernetically enhanced cops, are called in to investigate and stop the Puppetmaster. The pursuit will call into question what makes a human and what is the Puppetmaster in a world where the distinction between human and machine is increasingly blurry.\n(Source: ANN)","show_type":"Movie"},{"id":1411,"slug":"ghost-hunt","status":"Finished Airing","url":"https://hummingbird.me/anime/ghost-hunt","title":"Ghost Hunt","alternate_title":"","episode_count":25,"cover_image":"https://static.hummingbird.me/anime/poster_images/000/001/411/large/1411.jpg?1408443952","synopsis":"Telling ghost stories is a favorite past time of Mai Taniyama and her friends—that is, until she meets 17-year-old Kazuya Shibuya, the man sent by Shibuya Psychic Research Center to investigate paranormal activity at a supposedly haunted school. When Mai gets caught in a dangerous situation, she is rescued by Kazuya's assistant. Saving her lands the assistant incapacitated, and Kazuya demands that Mai become his assistant, instead. (Source: ANN)","show_type":"TV"},{"id":4135,"slug":"seven-ghost","status":"Finished Airing","url":"https://hummingbird.me/anime/seven-ghost","title":"07-Ghost","alternate_title":"","episode_count":25,"cover_image":"https://static.hummingbird.me/anime/poster_images/000/004/135/large/4135.jpg?1408451649","synopsis":"Set in a gothic fantasy world, this is the story of Teito Klein, an orphaned slave who became the top military academy student. However, an unexpected turn of events left him pursued by the forces of the Barsburg Empire. Now an escaping convict, Teito's sheltered by the church and its law of sanctuary. Here, he discovered many mysteries surrounding himself, the church, and the Empire itself. The fact that he might be connected to a dethroned king and the mystical stone of god, \"The Eye of Mikhael\", made him the target of the empire more than ever. Fortunately the church is under the mythical 7 Ghost protection. But who are the Ghosts really. Will Teito be free from the military's clutch, and what of his said mission to uncover the history. And who is the military's Chief-of-Staff Ayanami exactly. Teito's future seems to have spiraled into an unexpectedly perilous path.\r\n[Source: ANN]","show_type":"TV"},{"id":6391,"slug":"ghost-messenger","status":"Currently Airing","url":"https://hummingbird.me/anime/ghost-messenger","title":"Ghost Messenger","alternate_title":null,"episode_count":6,"cover_image":"https://static.hummingbird.me/anime/poster_images/000/006/391/large/6391.jpg?1408458272","synopsis":"Ghost Messengers are super-power agents from the underground world called the World of Death. The World of Death is a digitalized world with cutting-edge technologies that control and manage the life and death of all living things based on its elaborate systems.\r\nOur Ghost Messenger hero, Kang-lim, has been dispatched to the human world to capture the remaining ghosts who are refusing to go to the World of Death although it is their time.\r\nAn accident occurs during his mission and Kang-lim gets captured in his own mobile phone. Little Kang-lim, a human boy who has extraordinary spiritual powers, finds the mobile phone and takes GhostMessenger Kang-lim out from the mobile phone.\r\nAnd the adventure begins.\r\n(Source: Anime World Network)","show_type":"OVA"},{"id":2360,"slug":"shinreigari-ghost-hound","status":"Finished Airing","url":"https://hummingbird.me/anime/shinreigari-ghost-hound","title":"Shinreigari: Ghost Hound","alternate_title":null,"episode_count":22,"cover_image":"https://static.hummingbird.me/anime/poster_images/000/002/360/large/2360.jpg?1408446509","synopsis":"In an isolated region of Kyushu lies the town of Suiten.  Though seeming small and modest, Suiten is not a picturesque place for a vacation, unless it is from the “Unseen Worldâ€.  Taro, Makoto and Masayuki, three boys with traumatic pasts, learn to let their souls cross between the two parallel worlds.  However, the Unseen World is no mere copy of the real Apparent World.  The Unseen World is the home of ghosts, but changes are now allowing the souls of the dead to pass over into the Apparent World, with unpredictable effects.  Follow the journey of Taro, Makoto and Masayuki, as they cross between the two worlds, trying to unravel a great mystery. \n(Source: Sentai Filmworks)","show_type":"TV"}];
})();

动漫容器的html     

<div class="col-md-3 col-xs-6" ng-repeat="anime in animeListCtrl.anime">
    <!-- anime in anime list-->
    <div class="panel panel-default fixed-height highlight" ng-click="animeListCtrl.onSelectAnime(anime)">
        <div class="panel-body">
            <img class="img-rounded img-responsive center-block" ng-src="{{anime.cover_image}}"/>
            <h3> {{anime.title}} </h3>
        </div>
    </div>
</div>

我确信这是一个非常简单的解决方案,但我只找到了一些似乎使用旧版AngularJS的东西(我使用的是1.2.26)。

谢谢大家!

P.S。欢迎任何其他关于最佳实践的小费或建议!

1 个答案:

答案 0 :(得分:0)

您要做的是添加一项服务,然后将其注入其他控制器/指令。在您的示例中,我想象SearchService可以工作。在提交函数中,不是直接调用API,而是调用SearchService来执行搜索。然后,SearchService将维护并公开结果集。任何对显示结果感兴趣的控制器和/或指令都可以绑定到SearchService.resultSet,例如。

请记住,Angular服务是单例对象。因此,如果您打算拥有多个搜索表单/结果对象,则可能需要增强服务以存储命名搜索。但是,根据您显示的代码,看起来单个结果集就足够了。您可以选择将ctrl,directive,service作为动画特定模块的一部分进行装饰。因此,而不是SearchService称之为AnimeSearchService。

app.factory('AnimeSearchService', function($http) {
  var service = { resultSet: {} };

  service.executeSearch = function(args) { 
    ... some API calls ... 
    // when they return results store them as service.resultSet
  }

  return service;
});

然后在您的控制器中

app.controller('AnimeSearchController', function(AnimeSearchService){

    this.submit = function(srcstr){

        //here I call the API and then I want to update the anime variable in AnimeListController
        AnimeSearchService.executeSearch(srcstr);
        console.log(srcstr);
    }

});

app.controller('AnimeListController', function(AnimeSearchService){

    this.anime = AnimeSearchService.resultSet;     //expose the service to the template (or optionally create a $watch to update)

    this.onSelectAnime = function(anime){
        console.log(anime);
    };
});

更新:您的问题很可能归结为角度绑定。如果绑定到服务的resultSet对象的属性,那么这些绑定将随着这些属性的更改而更新。但是,如果要将属性的值分配给自己的控制器/作用域中的新属性,则必须观察该服务并更新控制器/作用域的副本。也许这个小提琴有助于更好地解释它:http://jsfiddle.net/vv3odc7t/1/

通常还有关于服务绑定的堆栈溢出问题:https://stackoverflow.com/a/23774843/1769529

希望有所帮助!