2012-11-06 24 views
0

我正在使用修改DOM的指令,因此必須在所有postLink fns被調用後完成。 (see angular-ui modules/directives/select2/select2.js:103如何在範圍內的所有指令準備好後運行事件?

給定某些先決條件(未在URL中編碼),我想將焦點設置爲頁面上的第一個select2元素。這是有問題的,因爲在設置焦點之前,select2必須被初始化,並且沒有一些低俗的任意延遲> 0,我不能安排要設置焦點的事件被廣播。

我已經創建了以下僞指令,它將偵聽焦點primaryInput /焦點事件並設置焦點。

# TODO - should we create a directive for tab order instead? 
app.directive "primaryInput",() -> 
    { 
    name: "primaryInput" 
    link: (scope, element, attrs) -> 
     scope.$on "primaryInput/focus", -> 
     element.focus() 
    } 

更改primaryInput指令優先級不起作用,因爲在調度setTimeout函數之前將運行任何優先級。

理想情況下,我希望能夠收集承諾,每個延遲指令推入堆棧,然後承諾一旦完成所有這些承諾就得到解決。我會把我的問題集中在如何最好地實現這一點上,但我可以想到一個不太好的方法,想探索更好的方法,並且想要避免XY problem

謝謝!

更新

通過這裏描述的問題,退一步的努力去後,我想到了一個可以接受的方法,以我的問題,並會回答我的問題,而是把它打開,如果任何人有一個更好的做法。

+0

因此,基本上如果我們知道select2的輸入模型已經準備就緒,我們可以廣播該事件。我對嗎 ?我試圖簡化你的問題 – maxisam

+0

我意識到這是一個非常複雜的問題,但我試圖不要過度指定。在退後一步思考後,我想到了一種不同的方法,結果變得更清潔。 –

回答

1

由於延遲執行的複雜性出現在處理Select2的指令中,所以我現在決定在那裏隔離這種複雜性。

我重寫了我的Select2指令中元素的焦點函數,因此焦點調用一旦可用就被轉發到select2實例。這樣,元素可以被告知在select2之前進行聚焦。

我關注的指令:

app.directive "input", ($injector) -> 
    primaryMatcher = (e,attrs) -> 
    attrs.primary? 
    { 
    name: "inputFocus" 
    restrict: 'E' 
    link: (scope, element, attrs) -> 
     scope.$on "focus", (e, matcher)-> 
     if ((matcher || primaryMatcher)(element, attrs)) 
      console.log("focus", element, attrs) 
      element.focus() 
    } 

在我選擇二指令:

app.directive "s2Factor",() -> 
    # ... 
    { 
    name: "s2Factor" 
    require: "?ngModel" 
    priority: 1 
    restrict: "A" 
    link: (scope, el, attr, controller) -> 
     select2_p = $.Deferred() 
     # ... 
     setTimeout -> 
     el.select2 opts 
     select2_p.resolve(el.data("select2")) 

     el.focus =() -> 
     select2_p.then (select2) -> 
      select2.focus() 
    } 

它涉及到例如猴子打補丁,但我覺得它是在這種情況下可以接受的。

相關問題