我正在构建一个Angular应用程序:一个培训引擎,它将向用户提供在线课程。
每门课程基本上都是一系列"幻灯片" - 用户可以按顺序浏览的HTML部分。每张幻灯片可以包含零个或多个不同类型的交互式小部件:简单的测验,动手练习等。
我的目标是让课程由纯HTML / CSS组成,这样技术水平较低的人就可以构建课程,而无需亲自使用JS或Angular。只要课程只包含静态HTML,这就没问题。但是当我想将交互式小部件添加到课程中时,它会变得棘手。
例如,一个示例课程" slide"可能看起来像这样:
<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或jqLite)来查找数据I&#39;我很感兴趣。
这是一种明智的做法吗?还有其他我想探索的方法吗?
问题2:其次,我需要在加载的HTML中使用测验模板的内容替换 div.quiz
,如下所示:
<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中是否有针对此问题的标准解决方案?或者整个方法完全是香蕉?
希望这是有道理的。感谢您提供的任何指导!
答案 0 :(得分:0)
正如@dandavis在上述评论中所建议的那样,答案是custom directives。
对于我的测验示例,我可以创建一个定义自定义元素的自定义指令。 (或者,我可以在指令定义中使用restrict: 'C'
来匹配<div class="quiz">
,或restrict: 'A'
以匹配<div quiz>
。)
然后,我将把所有的setup-and-DOM-massaging逻辑放在指令的链接函数中。
最后,我只需要向课程作者指明他们应该如何标记测验。
我还没有在实际代码中完全实现这一点,但我确信这一切都是准确的。