【问题标题】:Controller doesn't work after URL changeURL 更改后控制器不起作用
【发布时间】:2013-06-16 20:02:27
【问题描述】:

简而言之:

我有一个控制器,它在我的 AngularJS 网页中触发一些 jQuery 以淡出播放按钮和相应的图像。但是,当 URL 更改时,控制器无法处理后续页面。我使用的是动态 URL,我认为这就是我的控制器出现故障的原因。

详情

我通过为我的网站应用程序的每个页面设置一个控制器来组织我的控制器。在这里你可以看到我的路线是如何设置的:

angular.module('100_Ages', ['mydirectives', 'ngResponsiveImages']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
    when('/100_Ages', {templateUrl: 'partials/splash.html', controller: SplashCtrl}).
    when('/100_Ages/nav', {templateUrl: 'partials/nav.html', controller: NavCtrl}).
    when('/100_Ages/about', {templateUrl: 'partials/person-list.html', controller: AboutCtrl}).
    when('/100_Ages/0', {templateUrl: 'partials/splash.html', controller: SplashCtrl}).
    when('/100_Ages/:personId', {templateUrl: 'partials/person.html', controller: DetailCtrl}).
    otherwise({redirectTo: '/100_Ages'});
}]);

这里是有问题的控制器:

function DetailCtrl($scope, $routeParams, $http) {
// Pull down a JSON file with my data to populate Angular template
  $http.get('person.json').success(function(data) {
// matches person's id to route.
    angular.forEach(data, function(person) {
          if (person.id == $routeParams.personId) 
            $scope.person = person;
        });
    });
// start of attempt to integrate button click functionality.
  $scope.$on('$routeChangeSuccess', function(){
    $.noConflict();
      jQuery(function(){
        jQuery("#playButton").click(function(){
          jQuery("#person_photo").fadeOut('9000');
          jQuery("#playButton").fadeOut('9000');
          jQuery("#player").fadeIn('9000');
        });
      });
  });
}

我在这里使用 jQuery,因为我根本不知道如何在 Angular 中执行此操作。无论如何,当我刷新页面并单击按钮图像时,它可以工作。但是,我有一个“下一个”链接,该链接将路线增加“1”以转到我的应用程序的下一页(100 人的列表,每页一个人)。

当我使用此链接转到其他页面时,我的 jQuery 不再工作。我猜这是因为路由没有改变,即使 URL 是。无论如何要让我的动态路线工作?谢谢。

【问题讨论】:

  • 您也可以提供您的看法吗? DetailCtrl 是父控制器还是子控制器?

标签: javascript jquery angularjs angularjs-routing angularjs-controller


【解决方案1】:

几件事...

1) 你不需要$.noConflict()。 Angular 和 jQuery 玩得很好。

2) 您应该将 DOM 脚本放在 Angular 指令而不是控制器中。这是一个例子......

指令*:

(function () {

    function personPlayerDirective() {
        return function (scope, $element, attr) {
            $element.find('.play-btn').click(function () {
                $element.find(".img-person").fadeOut('9000');
                $element.find(".play-btn").fadeOut('9000');
                $element.find(".player").fadeIn('9000');
            });
        };
    }

    angular.module('app', [])
        .directive('personPlayer', [personPlayerDirective]);
}());

假设你的模板是*:

<div person-player>
    <img class="img-polaroid img-person" ng-src="{{person.imgUrl}}">
    <div class="player">
        I'm a player.
    </div>
    <div class="btn-group">
        <button class="btn play-btn">
            <i class="icon-play"></i> Play
        </button>
        <button class="btn pause-btn">
            <i class="icon-pause"></i> Pause
        </button>
        <button class="btn stop-btn">
            <i class="icon-stop"></i> Stop
        </button>
    </div>
</div>

3) 您可以使用带有 ng-click 的 CSS3 过渡来实现相同的行为,而无需任何 jQuery DOM 脚本...

新模板*:

<style>
    /* Twitter Bootstrap fade */
    .fade {
        opacity: 0;
        -webkit-transition: opacity 0.15s linear;
        -moz-transition: opacity 0.15s linear;
        -o-transition: opacity 0.15s linear;
        transition: opacity 0.15s linear;
    }
    .fade.in {
        opacity: 1;
    }
</style>

<div class="person-player">
    <img class="img-polaroid img-person fade {{imgPersonFade}}" ng-src="{{person.imgUrl}}">

    <div class="player fade {{playerFade}}">
        I'm a player.
    </div>
    <div class="btn-group">
        <button class="btn play-btn fade {{playBtnFade}}" ng-click="playing=true">
            <i class="icon-play"></i> Play
        </button>
        <button class="btn pause-btn">
            <i class="icon-pause"></i> Pause
        </button>
        <button class="btn stop-btn">
            <i class="icon-stop"></i> Stop
        </button>
    </div>
</div>

控制器*:

function DetailCtrl($scope, $routeParams, $http) {

    $scope.playing = false;

    // Update the *Fade scope attributes whenever the `playing` scope attribute changes
    $scope.$watch('playing', function (playing) {
        $scope.playerFade = playing ? 'in' : '';
        $scope.imgPersonFade = playing ? '' : 'in';
        $scope.playBtnFade = playing ? '' : 'in';
    });

    // Pull down a JSON file with my data to populate Angular template
    // ...

}

无论如何,就像许多新的 JS MV* 应用程序框架一样,Angular 鼓励您“观察”数据/模型的变化,而不是“监听”DOM 事件。事实上,我建议您尽可能少使用 jQuery,直到您掌握了这种新的范式转变的窍门。

* 代码未测试:)

【讨论】:

  • 成功!这次真是万分感谢。我知道在控制器中进行 DOM 操作不是最佳实践,但从概念上讲,我不知道如何使用指令来实现效果——同样不使用 jQuery 来实现。如果我有足够的代表来投票,我会的!
  • 不用担心投票...很高兴我能提供帮助。编码愉快!
  • 谢谢,同样,知道如何让 Angular 与 Vimeo api 对话,以便播放按钮真正触发底层 iFrame? Question here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 2012-11-09
  • 1970-01-01
  • 2017-11-09
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多