2013-12-23 7 views
0

Я строю свое первое приложение с угловыми углами, но у меня есть немного проблемы с работой над чем-то. У меня есть видеоконтейнер, который будет скрыт до $ scope.video.show = true; Я пытаюсь установить это значение, когда я нажимаю ссылку. Я пытаюсь сделать это в директиве. Любая помощь будет оценена по достоинству.AngularJS - изменить родительскую область из директивы?

HTML:

<div ng-controller="AppCtrl"> 
    <div ng-cloak 
     ng-class="{'show':video.show, 'hide':!video.show}"> 
        // youtube iframe content, for example 
    </div> 

    <div> 
     <ul> 
      <li> 
       <h3>Video Headline 1</h3> 
       <button type="button" 
        video-show 
        data-video-id="jR4lLJu_-wE">PLAY NOW&nbsp;&rang;</button> 
      </li> 
      <li> 
       <h3>Video Headline 2</h3> 
       <button type="button" 
        video-show 
        data-video-id="sd0f9as8df7">PLAY NOW&nbsp;&rang;</button> 
      </li> 
     </ul> 
    </div> 
</div> 

JavaScript:

var thisViewModel = angular.module("savings-video", []) 
.controller('SavingsVideoController', function($scope) { 

    $scope.video = { 
     show : false, 
     videoId : "" 
    }; 
}; 

thisViewModel.directive("videoShow", function(){ 
    return{ 
     restrict: 'A', 
     link: function(scope , element){ 

      element.bind("click", function(e){ 

       var $this = angular.element(element); 
       $this.closest('li').siblings().addClass('hide'); // hide the other one 
       $this.closest('li').removeClass('hide');   // keep me open 


       scope.video.show = true; // doesn't work. 
        // what is the best way to do this? 

      }); 
     } 
    } 
}); 
+0

Я хотел бы добавить рабочую демо-версию, чтобы получить быстрый ответ. – allenhwkim

+0

Если вы хотите изменить view.show в обработчике событий, вам нужно использовать '$ scope. $ Apply (function() {$ scope.view.show = true;});', чтобы перейти в цикл углового дайджеста , Но вам не нужно будет создавать директиву любым способом. Просто используйте 'ng-click' и' ng-show'. См. Мой ответ ниже. – Daiwei

ответ

1

Я вижу несколько вещей, которые вы можете улучшить.

  1. заказ ngShow/ngHide и ngIf; они дадут вам возможность переключения легче, чем пытаться сделать это с нуля.
  2. Think in angular. Вместо того, чтобы пытаться использовать логику для изменения DOM самостоятельно, просто настройте свои правила, используя угловые директивы, и пусть структура сделает для вас все остальное.

Например, кажется, что это больше того, чего вы хотите.

<div ng-controller="AppCtrl"> 
    <div ng-cloak ng-show='video.show"> 
       // youtube iframe content, for example 
    </div> 

    <div> 
     <ul ng-switch="video.videoId"> 
      <my-video my-video-id="jR4ABCD" my-headline="Video Headline 1" ng-switch-when="myVideoId" my-video-manager="video" /> 
      <my-video my-video-id="al1jd89" my-headline="Video Headline 2" ng-switch-when="myVideoId" my-video-manager="video"/> 
     </ul> 
    </div> 
</div> 

Что я изменил делаю свой IFrame шоу условно с ngShow, и с помощью ngSwitch управления, который появляется видео (явление видео основано на $ осциллограф video.videoId). Затем я повернул свои <li> S в директиву под названием my-video, который заканчивает тем, как этот

thisViewModel.directive("my-video", function(){ 
    return{ 
     restrict: 'E', 
     replace: true, 
     scope: { 
      myVideoId = "=", 
      myHeadline = "=", 
      myVideoManager = "=" 
     }, 
     template = '<li><h3>{{myHeadline}}</h3><button type="button" ng-click="play()">PLAY NOW&nbsp;&rang;</button></li>', 
     link: function(scope , element){ 
      scope.play = function(){ 
       myVideoManager.show = true; 
       /*whatever you want here, using scope.myVideoId*/ 
      } 
     } 
    } 
}); 

Эта директива делает именно то, что сделал ваш старый HTML, но приводит ее в угловую рамку, так что вы можете получить доступ к свойствам вы «Ищем. Используя необработанные угловые директивы, я устраняю необходимость в любой логике пользовательского интерфейса; Мне больше не нужно обращаться к element, и оба моих HTML и JavaScript более чисты. Конечно, здесь есть возможности для улучшения, но я бы сказал, что это ближе к правильному пути.

Для получения более подробной информации ознакомьтесь с правилами, но руководствоваться инструкциями по ссылке SO выше.

EDIT

К сожалению, думаю, что я пропустил требование в первый раз. Если вы хотите, чтобы оба видео показывались, когда ни один не выбран, не используйте ng-switch; просто настройте какое-то руководство ng-show s.

<div> 
     <ul> 
      <my-video my-video-id="jR4ABCD" my-headline="Video Headline 1" ng-show="myVideoId == video.videoId" my-video-manager="video" /> 
      <my-video my-video-id="al1jd89" my-headline="Video Headline 2" ng-show="myVideoId == video.videoId" my-video-manager="video"/> 
     </ul> 
    </div> 

Поскольку ng-switch действительно просто ярлык для ng-show в любом случае, это одно и то же; логика только что переместилась в атрибут ng-show.

Кроме того, если у вас есть масса видеороликов, выйдите из ng-repeat; он позволит вам повторять свой видеотег несколько раз автоматически, а не вручную.

<ul> 
    <my-video ng-repeat='aVideo in myVideoArray' my-video-id='aVideo.videoId' my-headline...(and so on)> 
</ul> 
+0

У меня это работает, но мне нужно показать оба видеоматериала, когда videoId = "". Могу ли я сделать ngShow (для учета «») в дополнение к ngSwitch (для учета заполненной видеоигры)? – Scott

+0

Я пропустил это ... ответ обновился. – Hylianpuffball

0

Ну ваши имена контроллеров не совпадают. Попробуйте изменить AppCtrl на SavingsVideoController.

0

Вам нужно только очень простое решение.

HTML

<div ng-controller="AppCtrl"> 
    <div ng-cloak ng-show="view.show"> 
     <!-- Use ng-show is more convenient --> 
    </div> 

    <div> 
     <ul> 
      <li> 
       <h3>Video Headline 1</h3> 
       <button type="button" 
        ng-click="view.show = true" 
        data-video-id="jR4lLJu_-wE">PLAY NOW&nbsp;&rang;</button> 
        <!-- You don't need an extra directive to change view.show --> 
      </li> 
      <li> 
       <h3>Video Headline 2</h3> 
       <button type="button" 
        ng-click="view.show = true" 
        data-video-id="sd0f9as8df7">PLAY NOW&nbsp;&rang;</button> 
      </li> 
     </ul> 
    </div> 
</div> 

JS

var thisViewModel = angular.module("savings-video", []) 
.controller('SavingsVideoController', function($scope) { 

    $scope.video = { 
     show : false, 
     videoId : "" 
    }; 
}; 

// No need to create another directive 
Смежные вопросы