2013-11-14 27 views
15

我正在使用「Video For Everybody」生成器將媒體播放器集成到我的應用中。如果瀏覽器不支持HTML5 videoaudio,則播放器的回退功能將閃回,因此必須使用視頻和佔位符(圖像)源創建object元素,並使用param屬性。AngularJS:非標準屬性上的ng-src行爲?

正如預期的那樣我碰上表達不能及時得到解決的經典問題,我的瀏覽器發送請求到my.media.com/{{video.src}}而不是my.media.com/somevideo.mp4

不幸的是有幾個屬性(poster, flashvars, placeholder僅舉幾例),我面臨着同樣的問題。我將如何去創建與ng-src或ng-href指令相同的行爲?我試圖尋找相關的源代碼,但我還沒有找到它。下面是一個片段,展示了有問題的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

你可以分享一些你不用的方法嗎? –

+0

在這一點上,我或多或少地在黑暗中磕磕絆絆,試圖找出是否可以應用自定義屬性,所以我認爲目前我的任何代碼都不會對題。我會盡快更新,只要我覺得我有什麼。 –

回答

8

查找內建指令的來源變得容易官方API文檔上。在這種情況下,請轉至ngSrc的文檔,在頁面頂部您將看到兩個按鈕「改善此文檔」和「查看源代碼」,單擊「查看源代碼」,它會自動將您帶到正確的源文件指令的定義。這適用於所有內置指令,非常方便!

在下面,我爲粘貼的ngSrc代碼,有趣的是看起來並不複雜可言,關鍵線路似乎是priority: 99的基礎上,旁邊的註釋就意味着99優先指令後,將運行屬性已被內插。

// 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]); 
     }); 
     } 
    }; 
    }; 
}); 

鑑於上述情況,實施自己的指令應該是微不足道的。

+0

太好了,非常感謝。簡直不敢相信我在Angular文檔中花了那麼多時間,並忽略了這個簡單而實用的功能。只是供參考:我會堅持接受/獎勵一段時間,以防萬一出現更多答案。 –

+0

@KGChristensen NP很高興我可以幫忙。 – Beyers

1

所以最通用的,可維護的,可配置的和可重用的解決方案是創建一個自定義指令來處理它。

看看這-->PLNKR<--幾乎所有你需要在那裏。你只需稍微弱一點。

工作原理:傳遞配置對象的指令(如果需要更多的對象,只需創建其他屬性)。元素可以處於兩種狀態:準備好與否。並且$scope.isReady只是說明是否收集了所有的成分。如果這樣的話加載videoPlayer模板,並且因爲所有的信息都在那裏,所以不會發送不需要的請求。

+0

感謝您的努力,雖然有一個固定的超時並不真正用戶友好或在這裏可行的選項。我設法使用$ observe創建我自己的ngSrc指令的實現來監視表達式解析。 –

+0

@KGChristensen你可能不瞭解代碼。使用'$ timeout'只是爲了證明這種方法**可以工作**,並且它在控制器中使用,而不是在指令本身中使用。指令等待填充範圍,檢查是否所有數據都已正確設置,並且僅加載模板。如何填充範圍是**完全不相關**:我使用'$ timeout',因爲它是最簡單的。如果您在控制器初始化時已經存在所有相關信息,該指令也可以工作。 –

+0

啊,對不起 - 現在再看一眼,上次有點快。儘管我可以看到這種方法的工作原理,但感覺有點麻煩:在數據準備就緒之前不包括模板,並不像使用指令方法的優勢(特別是與ngSrc方法相比)。 –

47

您現在可以使用ng-attr-poster或更一般地使用:ng-attr-whatever

+1

這對我有效!謝謝 –

1

我遇到了類似問題,poster屬性在video標籤上。如果你將ng-cloak應用於具有類似src屬性的元素,它們將不會嘗試加載任何東西,直到移除斗篷時它們變爲可見爲止。

+0

很好,謝謝你的更新。 –

相關問題