在模态angular js中,ng-click不起作用。

12 浏览
0 Comments

在模态angular js中,ng-click不起作用。

情况

在我们的Angular应用程序中嵌套了一个名为Page的指令,由一个控制器支持,其中包含一个带有ng-bind-html-unsafe属性的div。这个属性被指定给一个名为'pageContent'的$scope变量。这个变量从数据库中动态生成的HTML中赋值。当用户翻到下一页时,会调用数据库,并将pageContent变量设置为这个新的HTML,通过ng-bind-html-unsafe在屏幕上呈现。以下是代码:

Page指令

angular.module('myApp.directives')
    .directive('myPage', function ($compile) {
        return {
            templateUrl: 'page.html',
            restrict: 'E',
            compile: function compile(element, attrs, transclude) {
                // 目前什么都不做
                return {
                    pre: function preLink(scope, element, attrs, controller) {
                        // 目前什么都不做
                    },
                    post: function postLink(scope, element, attrs, controller) {
                        // 目前什么都不做
                    }
                }
            }
        };
    });

Page指令的模板(来自上面的templateUrl属性的"page.html")

   ...
   
   ...

Page控制器

angular.module('myApp')
  .controller('PageCtrl', function ($scope) {
        $scope.pageContent = '';
        $scope.$on( "receivedPageContent", function(event, args) {
            console.log( '从DB调用后收到新的页面内容' );
            $scope.pageContent = args.htmlStrFromDB;
        });
});

这样可以工作。我们可以在浏览器中看到来自数据库的页面HTML呈现得很好。当用户翻到下一页时,我们可以看到下一页的内容,以此类推。到目前为止还不错。

问题

问题在于我们希望在页面内容中包含交互式内容。例如,HTML可能包含一个缩略图,在用户点击缩略图时,Angular应该做一些很棒的事情,比如显示一个弹出模态窗口。我在我们的数据库中的HTML字符串中放置了Angular方法调用(ng-click),但是Angular当然不会识别这些方法调用或指令,除非它以某种方式解析HTML字符串、识别它们并编译它们。

在我们的数据库中

Page 1的内容:

这是一张很酷的狮子图片。  点击它查看大图。

Page 2的内容:

这是一条蛇。  点击它让它嘶嘶作响。

然后在Page控制器中添加相应的$scope函数:

Page控制器

$scope.doSomethingAwesome = function( id, action ) {
    console.log( "将执行 " + action + " 操作,使用 "+ id );
}

我无法弄清楚如何从数据库中的HTML字符串中调用那个'doSomethingAwesome'方法。我意识到Angular必须以某种方式解析HTML字符串,但是如何解析呢?我读过关于$compile服务的含糊的描述,复制粘贴了一些示例,但是没有任何作用。而且,大多数示例只在指令的链接阶段设置动态内容。我们希望Page在应用程序的整个生命周期中保持活动状态。它不断接收、编译和显示新内容,因为用户翻页。

抽象地说,我想我们可以说我们正在尝试在一个Angular应用程序中动态嵌套Angular的块,并且需要能够交换它们。

我多次阅读了各种Angular文档,以及各种博客文章,并在JSFiddle上尝试了人们的代码。我不知道我是完全误解了Angular,还是只是忽略了一些简单的东西,或者可能我比较慢。无论如何,我需要一些建议。

0
0 Comments

问题原因:ng-click在modal中不起作用。

解决方法:通过以下代码解决该问题。

var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
  $compile(element)($rootScope);
});

0
0 Comments

在angular 1.2.10版本中,scope.$watch(attrs.dynamic, function(html) {这行代码返回了一个无效字符错误,因为它试图监视attrs.dynamic的值,而这个值是html文本。

我通过从作用域属性中获取属性来修复了这个问题

 scope: { dynamic: '=dynamic'}, 

我的例子

angular.module('app')
  .directive('dynamic', function ($compile) {
    return {
      restrict: 'A',
      replace: true,
      scope: { dynamic: '=dynamic'},
      link: function postLink(scope, element, attrs) {
        scope.$watch( 'dynamic' , function(html){
          element.html(html);
          $compile(element.contents())(scope);
        });
      }
    };
  });

你好,如果我使用element.html,它会返回TypeError: Cannot call method 'insertBefore' of null。所以在一些关于这个问题的搜索中,我发现我必须使用element.append。但是,如果我在多个位置使用该指令,它会生成重复的HTML。所以2个指令会生成4个相同的HTML代码。谢谢你的回答。

我不会在你的情况下使用append,今晚我会看看并回复你。说实话,我在页面上的很多地方都使用了这个指令,并没有任何问题。我会尝试重现这个问题并回复你。

我刚刚测试了一下,发现我的代码即使在1.2.12版本下也能正常运行。我认为你可能忽略了HTML中的声明<div dynamic="html">吗?(有了这个声明,$watch会监视作用域中的'html'属性,而不是实际的HTML,所以不应该有无效字符错误。)如果没有,请给我一个不能工作的plunkr,我会看看是什么问题。

你可能是对的。当时我一直期望html实际上是一个包含html的变量:P。不过在你的指令中设置作用域是一个好主意。 umur.io/…

$compile(ele.contents())(scope); - 这一行解决了我动态添加的angular组件没有编译的问题。谢谢。

0
0 Comments

ng-click在模态angular js中不起作用的原因是ng-bind-html-unsafe仅将内容呈现为HTML,而不将Angular作用域绑定到生成的DOM上。为了解决这个问题,需要使用$compile服务。以下是解决方法的代码示例:

demo.html

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script data-require="angular.js.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <h1>Compile dynamic HTML</h1>
    <div ng-controller="MyController">
      <textarea ng-model="html"></textarea>
      <div dynamic="html"></div>
    </div>
  </body>
</html>

script.js

var app = angular.module('app', []);
app.directive('dynamic', function ($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function (scope, ele, attrs) {
      scope.$watch(attrs.dynamic, function(html) {
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
});
function MyController($scope) {
  $scope.click = function(arg) {
    alert('Clicked ' + arg);
  }
  $scope.html = '<a ng-click="click(1)" href="#">Click me</a>';
}

希望这个解决方法对你有帮助!

0