2013-11-14 9 views
15

Integruje się odtwarzacz multimedialny w mojej aplikacji przy użyciu generatora "Video For Everybody". Ponieważ odtwarzacz ma funkcję awaryjnego flashowania, jeśli przeglądarka nie obsługuje HTML5 video i audio, muszę zbudować element object z atrybutami param ze źródłem wideo i symbolem zastępczym (obrazem).AngularJS: zachowanie ng-src na niestandardowych atrybutach?

Jak oczekiwano biegnę do klasycznego problemu wyrażeń nie zostanie rozwiązany w czasie, moja przeglądarka wysyła żądania do my.media.com/{{video.src}} a następnie my.media.com/somevideo.mp4

Niestety istnieje kilka atrybuty (poster, flashvars, placeholder aby wymienić tylko kilka), gdzie twarz taka sama problem. W jaki sposób chciałbym stworzyć takie samo zachowanie, jak dyrektywy ng-src lub ng-href? Próbowałem wyszukać odpowiedni kod źródłowy, ale go nie znalazłem. Oto fragment, który prezentuje problematyczne HTML,

<video controls="controls" poster="{{mediaModel.mediaFile2}}" width="300" height="150"> 
<source ng-src="{{mediaModel.mediaFile}}" type="{{mediaModel.contentType}}" /> 
<object type="application/x-shockwave-flash" data="http://player.longtailvideo.com/player.swf" width="300" height="150"> 
    <param name="movie" value="http://player.longtailvideo.com/player.swf" /> 
    <param name="allowFullScreen" value="true" /> 
    <param name="wmode" value="transparent" /> 
    <param name="flashVars" value="{{'controllerbar=over&amp;image=' + media.mediaFile2 + '&amp;file=' + mediaModel.mediaFile}}" /> 
    <img ng-src="{{mediaModel.mediaFile2}}" width="300" height="150" title="{{mediaModel.uploadedTime}}" /> 
</object> 

+0

Czy możesz podzielić się niektórymi z podejść, które nie działają? –

+0

W tym momencie jestem mniej lub bardziej potyka się w ciemności, próbując dowiedzieć się, czy jest to w ogóle możliwe do zastosowania niestandardowego atrybutu, więc nie sądzę, że którykolwiek z kodu, który mam w tym momencie będzie konstruktywny do pytanie. Oczywiście zaktualizuję się, gdy tylko poczuję, że coś mam. –

Odpowiedz

8

Znalezienie źródła dyrektywy wbudowany jest łatwe na oficjalnej dokumentacji API. W takim przypadku przejdź do dokumentacji ngSrc, u góry strony zobaczysz dwa przyciski: "Ulepsz ten dokument" i "Wyświetl źródło", kliknij "Wyświetl źródło" i automatycznie przeniesie Cię do właściwego pliku źródłowego gdzie zdefiniowana jest dyrektywa. Działa to na wszystkich dyrektywach wbudowanych, bardzo przydatne!

Poniżej jestem wklejając kod ngSrc, która co ciekawe nie wygląda wcale skomplikowana, kluczowa linia wydaje się być priority: 99, w oparciu o komentarzu obok Oznacza to, że wytyczne z pierwszeństwem od 99 zostanie uruchomiony po Atrybuty zostały interpolowane.

// ng-src, ng-srcset, ng-href are interpolated 
forEach(['src', 'srcset', 'href'], function(attrName) { 
    var normalized = directiveNormalize('ng-' + attrName); 
    ngAttributeAliasDirectives[normalized] = function() { 
    return { 
     priority: 99, // it needs to run after the attributes are interpolated 
     link: function(scope, element, attr) { 
     attr.$observe(normalized, function(value) { 
      if (!value) 
      return; 

      attr.$set(attrName, value); 

      // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist 
      // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need 
      // to set the property as well to achieve the desired effect. 
      // we use attr[attrName] value since $set can sanitize the url. 
      if (msie) element.prop(attrName, attr[attrName]); 
     }); 
     } 
    }; 
    }; 
}); 

Biorąc pod uwagę powyższe, wdrożenie własnej dyrektywy powinno być trywialne.

+0

Świetnie, dziękuję bardzo.Nie mogę uwierzyć, że spędziłem tyle czasu w Angularnych dokumentach i przeoczyłem tę prostą, ale bardzo praktyczną cechę. Tylko FYI: Będę przez jakiś czas akceptować/nagradzać nagrodę za bounty, na wypadek, gdyby pojawiły się więcej odpowiedzi. –

+0

@KGChristensen NP cieszę się, że mogłem pomóc. – Beyers

1

Najbardziej typowe, możliwe do utrzymania, konfigurowalne i wielokrotnego użytku rozwiązanie polega na utworzeniu niestandardowej dyrektywy, która poradzi sobie z tym rozwiązaniem.

Spójrz na to -->PLNKR<-- jest tam praktycznie wszystko, czego potrzebujesz. Trzeba go trochę osłabić.

Jak to działa: do dyrektywy przekazujesz obiekt konfiguracyjny (jeśli potrzebujesz więcej obiektów, po prostu stwórz dodatkowe atrybuty). Element może być w dwóch stanach: gotowy lub nie. I $scope.isReady po prostu stwierdza, czy wszystkie składniki zostały zebrane. Jeśli tak, to ngSwitch wczytuje szablon videoPlayer, a ponieważ wszystkie informacje tam są, nie są wysyłane żadne niepożądane żądania.

+0

Dzięki za wysiłek, chociaż posiadanie ustalonego limitu czasu nie jest tak naprawdę przyjazne dla użytkownika lub realną opcją tutaj. Udało mi się stworzyć własną implementację dyrektywy ngSrc za pomocą polecenia $ obserwuj, aby obejrzeć, jak rozwiązuje się wyrażenie. –

+0

@KGChristensen prawdopodobnie nie rozumiesz kodu. Używanie '$ timeout' miało jedynie pokazać, że to podejście ** działa ** i zostało użyte w kontrolerze, a nie w samej dyrektywie. Dyrektywa czeka na zapełnienie zakresu, sprawdza, czy wszystkie dane są ustawione prawidłowo i tylko ładuje szablon. Sposób zapełnienia zakresu jest ** całkowicie nieistotny **: Użyłem '$ timeout', ponieważ było najłatwiejsze. Jeśli masz już wszystkie istotne informacje, gdy kontroler jest inicjowany, dyrektywa również będzie działać. –

+0

Ahh, przepraszam za to - jeszcze raz rzuciłem okiem, był ostatnio trochę szybki. Chociaż widzę, że to podejście działa, wydaje się nieco uciążliwe: nie uwzględnienie szablonu, zanim dane będą gotowe, nie wydaje się, aby grać mocnymi stronami podejścia dyrektywy (zwłaszcza w porównaniu z podejściem ngSrc). –

47

Można teraz użyć ng-attr-poster lub bardziej ogólnie: ng-attr-whatever.

+1

To zadziałało dla mnie! Dzięki –

1

Wpadłem na podobny problem z atrybutem poster na tagu video. Jeśli zastosujesz ng-cloak do elementów, które mają atrybuty podobne do src, nie będą próbowały ładować niczego, dopóki nie staną się widoczne po zdjęciu płaszcza.

+0

Miło, dzięki za aktualizację. –

Powiązane problemy