简体   繁体   中英

How to add a html button with angularjs with a working ng-click function

I am working on a game made with angularjs. I have one problem that I haven't been able to solve yet. I would like to use a popup dialog ( no alert ) whose content depends on the context. This popup contains a button, that when clicked starts the game.

Since the content is dynamic the ng-click function does not work.

I've tried with directives and straight from the controller but have not gotten it to work.

My concrete question is how do I add HTML Button to a with angularjs that contains a ng-click function that will actually fire?

Edit: here one attempt (that actually gets the button to show, but ng-click does nothing): Controller:

    {
       if ($scope.quiz.state === 'finished' || $scope.quiz.state === 'initialized') {
           var startButton = '<br><br><button data-ng-click="startQuiz">start quiz</button>';
           $scope.popupText = $sce.trustAsHtml('Stating ' + quiz.name + startButton);
           $scope.showStart = false;
           $scope.showPopup = true;
       }
    };
    $scope.startQuiz = function() {
        $scope.showPopup = false;
        if ($scope.quiz.state === 'initialized') {
             $scope.quiz.start();
             $scope.quizTimer.start($scope, $timeout);
        }
    };

Html:

<div id="popupBox">
    <div id="closePopup" data-ng-click="closePopup()">X</div>
    <div data-ng-bind-html="popupText"></div>
</div>

Using the help from the other answers I got it to work by doing the following (this is probably not the best way, but it works. Please comment if there is someway to improve this.):

Controller:

    ...
    $scope.compiledStartPopupText = $compile(angular.element('<br><br><button data-ng-click="startQuiz()">start quiz</button>'))($scope);
    $scope.popupText = 'Starting ' + $scope.quiz.name;
    $scope.getCompiledStartPopupText = function() {
        return $scope.compiledStartPopupText;
    };
    $scope.openStartQuizPopup = function()
    {
        if ($scope.quiz.state === 'finished' || $scope.quiz.state === 'initialized') {
            if($scope.quiz.state === 'finished') {
                $scope.quiz.reinitialize();
            }
            $scope.showPopup = true;
        }
    };
    $scope.closePopup = function() {
        $scope.showPopup = false;
        if($scope.quiz.state !== 'started') {
            $scope.showStart = true;
        }
    };
    $scope.startQuiz = function() {
        $scope.showStart = false;
        $scope.showPopup = false;
        if ($scope.quiz.state === 'initialized') {
            $scope.quiz.start();
            $scope.quizTimer.start($scope, $timeout);
        } else if ($scope.quiz.state === 'finished') {
            $scope.quiz.restart();
            $scope.quizTimer.restart($scope, $timeout);
        }
    };
    $scope.endGame = function()
    {
        $scope.quiz.state = 'finished';
        $scope.showPopup = true;
        $scope.showStart = true;
    };
    ...

Directive:

    directive('popUp', function() {
        return {
            restrict: 'A',
            link: function($scope, elm, attrs) {
                $scope.$watch('quiz.state', function(value){
                    if(value === 'finished') {
                        elm.html('finished');
                    } else {
                        var compiledStartButton = $scope.getCompiledStartPopupText();
                        elm.html($scope.popupText);
                        elm.append(compiledStartButton);
                    }
                });
            }
        };
    };

HTML:

    <div id="popup" ng-show="showPopup">
        <div id="popupBox">
            <div id="closePopup" data-ng-click="closePopup()">X</div>
            <div data-pop-up class="cta"></div>
        </div>
    </div>

If you are trying to call closePopup() , let's say your app is initialized at the top of the html and you have a ng-controller="MsgCtrl" as well, within the controller have your code

<div id="popupBox">
    <div id="closePopup" data-ng-click="closePopup()">X</div>
    <div data-ng-bind-html="popupText"></div>
</div>

and then in the script of your app, write something like this

function MsgCtrl($scope) {
    $scope.closePopup = function () {
        console.log("function called");
    };
}

Look at this for a similar example and experiment with it.

By using the $compile service , you can evaluate arbitrary HTML in the context of a certain scope. Example:

var element = $compile(angular.element('<button ng-click="doSomething()"></button>'))(scope);

The variable element then contains an angular.element (or jQuery if you are using it) that you can insert anywhere in the DOM. Clicking the button will result in an invocation of scope.doSomething() . Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM