13

我正在尝试使用 AngularJS 为 HTML 创建一个指令,以便我可以在浏览器中呈现 Markdown。我想要的是有一个<markdown>带有src属性的标签,它将加载指定的文件并正确呈现它。

我已部分实施如下 -

function Main($scope) {
    $scope.theContent = '#asgakfgajgfas\n##akfaljfqpo\ndhvkajvlbndvm';
};

angular.module('myApp', [])
    .directive("markdown", function ($compile) {
    return {
        restrict: 'E',
        require: 'model',
        scope: {
            value: "=model"
        },
        template: '<div ng-bind-html-unsafe="value | markdown"></div>'
    };
}).filter('markdown', function () {
    var converter = new Showdown.converter();
    return function (value) {
        return converter.makeHtml(value || '');
    };
});

以及相应的 HTML -

<div ng-controller="Main">
    <markdown model="theContent"></markdown>
</div>

这是上述代码的jsFiddle 链接(基于 John Linquist 的示例)。这不适用于该src属性,但它能够加载模型中指定的降价文本字符串。

您能否告诉我如何更改此代码以加载src标签中指定的文件。我正在考虑使用$httpAngularJS 提供的,但无法在指令定义中实际使用它。

我想要实现的是<markdown src="a/b/c.md" />

4

3 回答 3

21

我终于想出了一个解决方案。

// Render markdown in the HTML page
app.directive("markdown", function ($compile, $http) {
    var converter = new Showdown.converter();
    return {
        restrict: 'E',
        replace: true,
        link: function (scope, element, attrs) {
            if ("src" in attrs) {
                $http.get(attrs.src).then(function(data) {
                    element.html(converter.makeHtml(data.data));
                });
            } else {
                element.html(converter.makeHtml(element.text()));
            }
        }
    };
});

我定义了一个自定义link函数,它要么获取<markdown>标签的内容并正确呈现它们,要么获取src属性中给定的文件的内容并呈现它。

于 2013-03-10T12:53:16.233 回答
6

另一种选择,基于上面的答案。这个使用 angular eval、watch 和 sanitize,这意味着它对实时编辑很有用,清理 html,这是必要的,因为 markdown 将内联 html (如脚本标签)保持原样,并使用 angular 表达式来访问数据.

采用

控制器:

 $scope.data = {markdown:"#H1"} 

看法:

<div markdown="data.markdown">
</div>

<textarea ng-model="data.markdown"></textarea>

代码:

angular.module('markdown',['ngSanitize']).directive('markdown', function ($sanitize) {
    var converter = new Showdown.converter();
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            function renderMarkdown() {
                var htmlText = converter.makeHtml(scope.$eval(attrs.markdown)  || '');
                element.html($sanitize(htmlText));
            }
            scope.$watch(attrs.markdown, function(){
                renderMarkdown();
            });
            renderMarkdown();
        }
    }
});
于 2014-02-10T18:17:18.917 回答
3

这是我可以召集的最简单的通用解决方案,因为不需要使用 $sanatize 或 $sce :

http://plnkr.co/edit/6OK0RcMChmD1S3JtfItp?p=preview

  <body ng-app="myApp">

    <textarea ng-model="test"></textarea>
    <div markdown="test"></div>
    
    <script src="//code.angularjs.org/1.3.0/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>

    <script>
      angular.module('myApp', [])
        .run(function($rootScope) {
          $rootScope.test = '#foo\r- bar\r- baz'
        })
        .directive('markdown', function () {
              var converter = new Showdown.converter();
              return {
                  restrict: 'A',
                  link: function (scope, element, attrs) {
                      function renderMarkdown() {
                          var htmlText = converter.makeHtml(scope.$eval(attrs.markdown)  || '');
                          element.html(htmlText);
                      }
                      scope.$watch(attrs.markdown, renderMarkdown);
                      renderMarkdown();
                  }
              };
          });
    </script>
  </body>

结果:

  • 酒吧
  • 巴兹
于 2014-10-23T17:56:51.650 回答