2015-05-21 24 views
4

我正在構建一個Angular應用程序:一個向用戶展示在線課程的培訓引擎。如何使用Angular從vanilla(非Angular)HTML創建交互式小部件?

每個課程基本上都是一系列「幻燈片」 - 用戶可以依次瀏覽的HTML部分。每個幻燈片可以包含零個或多個不同類型的交互式小部件:簡單測驗,動手練習等。

我的目標是讓課程由純HTML/CSS組成,這樣技術人員就可以在沒有不得不用JS或Angular弄髒自己的手。只要課程只包含靜態HTML,就沒有問題。但是,當我想將交互式小部件添加到課程時,會變得棘手。

例如,一個樣品課程「幻燈片」可能是這樣的:

<p>Here's some static content introducing the quiz.</p> 

<div class="quiz"> 

    <ol class="questions" data-passing-score="50"> 
     <li> 

      <p>What was Abraham Lincoln's last name?</p> 

      <ul class="answers"> 
       <li>Smith</li> 
       <li>Johnson</li> 
       <li class="correct">Lincoln</li> 
       <li>Liebowitz</li> 
      </ul> 

     </li> 
     <li> 

      <p>What were George Washington's false teeth made of?</p> 

      <ul class="answers"> 
       <li>Particle board</li> 
       <li class="correct">Wood</li> 
       <li>The bones of his enemies</li> 
       <li>Advanced space-age polymers</li> 
      </ul> 

     </li> 
    </ol> 

</div> 

<p>Here's some static content that appears after the quiz.</p> 

...,當這個HTML文件被加載(可能通過$http.get()),我的應用程序會注意到它包含一個div與類quiz,並將設置所需的交互性:調整標記的結構(,例如,添加單選按鈕和提交按鈕),可能隱藏和顯示元素(這樣用戶只會看到一個問題時間),提交評分等。

這是jQuery-land中很常見的模式。當然,我們不是 jQuery-land。

如果我正確地思考這個問題,我需要解決兩個問題才能完成這項工作。

問題1:首先,我需要將測驗數據從原始HTML和JavaScript對象中提取出來。例如,我可以解析HTML成以上這樣的結構:

var quiz = { 
    passing_score: 50, 
    questions: [ 
     { 
      ask: "What was Abraham Lincoln's last name?", 
      answers: [ 
       { text: "Smith", correct: false }, 
       { text: "Johnson", correct: false }, 
       { text: "Lincoln", correct: true }, 
       { text: "Liebowitz", correct: false } 
      ] 
     }, 
     ... 
    ] 
}; 

我想我要加載的HTML轉換成DOM樹(只是在內存中,而不是附加給文檔),以及然後探索它(使用jQuery或jqLit​​e)來查找我感興趣的數據。

這是一個明智的方法嗎?我可能想要探索其他方法嗎?

問題2:其次,我需要與測驗模板的內容替換div.quiz在加載HTML,就像這樣:

<form ng-controller="QuizController as quizCtrl" ng-submit="quizCtrl.submit()"> 

    <ol> 
     <li ng-repeat="question in quizCtrl.questions"> 
      <p ng-bind-html="question.ask"></p> 
      <ul> 
       <li ng-repeat="answer in question.answers"> 
        <label> 
         <input type="radio" ng-attr-name="{{ 'q' + $parent.$index }}" ng-model="question.selected_answer" ng-value="answer"> 
         <span ng-bind-html="answer.text"></span> 
        </label> 
       </li> 
      </ul> 
     </li> 
    </ol> 

    <button type="submit">Score Quiz</button> 

</form> 

...和DIV結合QuizController。

如何動態綁定特定的DOM節點到特定的控制器?我如何獲得測驗對象(我在前一步中構建的)控制器的範圍?

在Angular-land中是否存在標準解決方案?或者這整個方法完全是香蕉?

希望這是有道理的。感謝您提供的任何指導!

+1

我的第一個直覺是,如果你的理由讓香草HTML只是爲了簡單起見將其轉換爲另一個模板,爲什麼不用START開始使用JSON?讓人們在問題1中寫下類似問題的測驗,在控制器中獲取這些內容,甚至可以只有一個控制器 – azium

+0

聽起來像是我的指示...... – dandavis

+0

@azium:這是一個很好的觀點,我自己想到了這一點。但是,這隻會產生新問題:測驗作者如何在HTML文件中聲明應該呈現測驗的地方?現在測驗作者需要知道HTML *和* JSON,必須爲單張幻燈片處理多個文件,並且需要處理奇怪的非標準HTML標記或屬性(因爲他們大概需要使用類似的東西來指示哪裏應該將JSON定義的測驗插入到標記中,並且應該在那裏呈現* which * quiz JSON)。 – greenie2600

回答

0

作爲@dandavis在上面的評論中提出的答案是custom directives

對於我的測驗示例,我可以創建一個定義自定義元素的自定義指令。 (或者,我可以用restrict: 'C'在我的指令定義匹配<div class="quiz">,或restrict: 'A'來匹配<div quiz>

然後,我硬是把我所有的設置和-DOM-按摩邏輯指令的鏈接功能。

最後,我只需要指定課程作者如何標記測驗。

我還沒有完全在真正的代碼中演示過這一點,但我很確定這完全正確。

相關問題