2013-10-14 2 views
1

Кажется, я неправильно понял, как работает функция $. Из следующего примера (plunker link).

HTML

<html ng-app="record"> 

    <head> 
    <script data-require="[email protected]*" data-semver="1.2.0-rc2" src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script> 
    <link rel="stylesheet" href="style.css" /> 
    <script src="script.js"></script> 
    </head> 

    <body ng-controller="IndexController"> 
    <input type="text" value="{{src}}"/> 
    <input type="text" value="{{RecordAddress}}"/> 
    <input type="text" value="{{FlashVars}}"/> 
    <input type="button" ng-click="handleClick()" value="click me"/> 
    <record src="{{src}}"></record> 
    </body> 

</html> 

JS

angular.module('record',[]) 
.controller("IndexController", function($scope) 
{ 
    console.log('controller called') 
    $scope.handleClick = function() 
    { 
    console.log('handleClick - called'); 
    $scope.RecordAddress = 'rtmp://thisIsAnAddress'; 
    $scope.FlashVars = 'userid=SomeId&filename=http://localhost/Content/ThisIsAnAddress/player.swf&mediaFormat=_video.mp4&mediaServerAddress=rtmp://ThisIsAnAddress&culture=en-GB' 
    $scope.src = $scope.RecordAddress+ '`' + $scope.FlashVars; 
    } 
}) 
.directive('record', function ($location) { 
      return { 
       restrict: 'E', 
       scope: { 
        current: '=current' 
       }, 
       link: function ($scope, element, attr) { 
        console.log('record directive - called'); 
        console.log(attr); 

        attr.$observe('src', function(value) 
         { 
          console.log('record observe callback called!'); 
          console.log('The value is: '+ value); 
          if(value && value !='recordValues') 
          { 
           var values = value.split('`'); 
           console.log('video values:') 
           console.log(values); 
           element.html('<object position="relative" width="519px" height="520px" data="'+values[0]+'" type="application/x-shockwave-flash"><param name="FlashVars" value="'+values[1]+'" /><param name="AllowScriptAccess" value="always" /></object>'); 
          } 
          else 
          { 
           element.html("<div>Please wait</div>") 
          } 
         } 
        ); 
       } 
      } 
     }); 

Я бы ожидать, что "объект", чтобы быть оказаны при нажатии на кнопку в отличие от "Пожалуйста, подождите", что должно появляются, когда настройки не готовы. Однако он не вызывается, когда атрибут «src», по-видимому, обновляется. Может ли кто-нибудь объяснить мне, почему этот пример не работает?

+0

Я думаю, вы должны смотреть на это тоже: http://docs.angularjs.org/api/ng.directive:ngSrc – unludo

ответ

2

Я думаю, что у вас сразу есть несколько вещей, которые всегда приносят удовольствие от отладки. Я подозреваю, что $ watch может работать лучше для вас. Но также, используя вызовы element.html(), была перезаписана переменная в html, которую вы пытались посмотреть.

Я внес несколько изменений (все из которых содержится в вашей директиве) и у вас есть рабочий код ниже (где я добавил шаблон для размещения вашего сообщения, конечно, есть множество других способов сделать то же самое) ,

directive('record', function ($location,$sce) { 
     return { 
      restrict: 'E', 
      template: '<div ng-bind-html="trustedMsg"></div>', 
      link: function ($scope, element, attr) { 
       console.log('record directive - called'); 
       console.log(attr); 

       $scope.$watch('src', function(value) 
        { 
         console.log('record observe callback called!'); 
         console.log('The value is: '+ value); 
         if(value && value !='recordValues') 
         { 
          var values = value.split('`'); 
          console.log('video values:') 
          console.log(values); 
          $scope.message='<object position="relative" width="519px" height="520px" data="'+values[0]+'" type="application/x-shockwave-flash"><param name="FlashVars" value="'+values[1]+'" /><param name="AllowScriptAccess" value="always" /></object>'; 
          $scope.trustedMsg = $sce.trustAsHtml($scope.message); 
         } 
         else 
         { 
          $scope.message="<div>Please wait</div>"; 
          $scope.trustedMsg = $sce.trustAsHtml($scope.message); 
         } 
        } 
       ); 
      } 
     } 
    }); 

Также, если вы предпочитаете придерживаться своего attr.$ Наблюдать вызов, то вы можете изменить HTML от:

<record src='{{src}}'></record> 

к:

<record src='src'></record> 

Edit: я обновил (и тестировалось) код так сообщение теперь поддерживает HTML, так как ваш код делает. (http://plnkr.co/edit/K18Djio1NfSaHIWOXpeJ))

+0

Я люблю этот код, но $ sce только 1.2? Что мы делали до этого? – Quibblesome

+0

@Quibblesome, вы правы, что $ sce был включен по умолчанию, начиная с 1.2. Но есть легкое решение до 1.2. До 1.2 вы можете использовать 'ng-bind-html-unsafe' (который был удален в 1.2). Итак, для pre-1.2 просто удалите ссылки на $ sce и используйте 'ng-bind-html-unsafe' вместо' ng-bind-html' (и, очевидно, передайте 'message' вместо' trustedMsg' (который вы удалили, когда вы удалили ссылки $ sce)) – KayakDave

+0

Отлично, спасибо за отзыв sir! – Quibblesome

1

Я думаю, что вы неправильно используете функцию $ observ, хотя я могу просто не понимать 100% того, что вы пытаетесь сделать. Я думаю, что лучший способ сделать то, что вы хотите, будет иметь правильное значение src на вашем $scope в вашем контроллере, а затем используйте $watch для обнаружения изменений этого значения. Далее, как я хотел бы предложить вам сделать это:

В контроллере:

$scope.handleClick = function(){ 
    console.log('handleClick - called'); 
    $scope.RecordAddress = 'rtmp://thisIsAnAddress'; 
    $scope.FlashVars = 'userid=SomeId&filena...'; 

    //Now set the src on the scope as you already had: 
    $scope.source = $scope.RecordAddress+ '`' + $scope.FlashVars; 
} 

В вашей точки зрения HTML:

<!-- remove the binding braces so you're just passing a regular attribute --> 
<record src="source"></record> 

В вашей директиве:

//add a simple update function (for cleanliness) 
function update(value){ 
    if(value && value !='recordValues'){ 
     var values = value.split('`'); 
     element.html('INSERT YOUR LONG HTML STRING HERE'); 
    }else{ 
     element.html("<div>Please wait</div>") 
    } 
} 

// get any initial value for the 'source' variable 
var value = scope.$eval(attrs.src); // this will return the scope's source variable 
if(value) update(value); 

// watch for any changes to that variable on the scope 
scope.$watch(attrs.src, update); 

NOTE : Хотя я считаю, что приведенный выше код будет работать для вас, я думаю, что это не лучший способ сделать это. Вы действительно передаете два значения своей директиве от своего контроллера: 1) RecordAddress и 2) FlashVars. Я хотел бы предложить вам добавить две отдельные атрибуты для вашего record элемента:

<record address="addr" flash-vars="flashVars"></record> 

И тогда вы привяжите к ним отдельно от директивы как:

function update(addr, flashVars){ ... } 

scope.$eval(addrs.address, function(value){ ... }); 
scope.$eval(addrs.flashVars, function(value){ ... }); 

scope.$watch(addrs.address, ...); 
scope.$watch(addrs.flashVars, ...); 

Это избавит вас от необходимости расколоть значения в директиве.

+0

спасибо за комментарий! Дэйв Каяк выиграл свой полный пример, но я действительно хотел выразить благодарность за то, что помог мне здесь. Благодарю !!!! :) – Quibblesome

4

Для директив с изолированной областью элемент, к которому вы применяете директиву, не наследует область действия родителя. Таким образом, вы не увидите никакой переменной {{src}} - она ​​всегда будет пустой.

Есть два способа вы можете общаться с внешним миром, используя атрибуты директивы с изолированным объемом:

  • Использованием src="{{$parent.src}}", но это немного хаком
  • Использования @ отображение атрибутов для односторонних связываний
scope: { 
    src: '@src' 
} 

И тогда следующий код будет работать:

$attrs.$observe('src', function(value) { 
    //some action 
}); 
+0

Извините, я не выбрал этот ответ, но KayakDave создал полный образец. То, что я люблю о вас, хотя и учит меня немного больше об изолированных областях. «Копирование поверх» src в объявлении области очень круто, и я не знал, что это сработало таким образом, поэтому я хотел выразить благодарность лично за это. :) – Quibblesome

+1

Конечно, но на самом деле я думаю, что в вашем случае вы должны использовать $ observ, потому что для 'src' существует только один способ привязки. Вы не меняете его обратно из директивы во «внешний мир». А также $ наблюдать немного быстрее, чем $ watch. – kseb

Смежные вопросы