AngularJS中的自定义指令和路由

孤独主义者

我对AngularJS和Javascript还是很陌生,但是我设法将一个自定义的camera指令放到一起,以我想要的方式工作。它使我可以从可用的照相机列表中选择照相机,拍摄快照,显示所拍摄的照片并具有用于保存照片或关闭照片的按钮。问题是,当我将路由添加到应用程序时,单击按钮将不再发生任何事情。所以我的问题是,与应用程序一起使用路由时,如何使该指令像以前一样工作?

这是指令:

app.directive('camera', function () {
return {
    template: '\
    <div ng-show="showVideo">\
        <div class="select">\
            <label for="videoSource">Video source: </label><select id="videoSource"></select>\
        </div>\
        <video id="video" width="640" height="480" autoplay></video>\
        <button id="snap">Snap Photo</button>\
    </div>\
    <div ng-show="showSnap">\
        <canvas id="canvas" width="640" height="480"></canvas>\
        <button id="save">Save Photo</button>\
        <button id="cancel">Cancel</button>\
    </div>',
    link: function ($scope) {

        $scope.showVideo = true;
        $scope.showSnap = false;

        var videoElement = document.querySelector('video');
        var videoSelect = document.querySelector('select#videoSource');

        navigator.getUserMedia = navigator.getUserMedia ||
            navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

        function gotSources(sourceInfos) {
            for (var i = 0; i !== sourceInfos.length; ++i) {
                var sourceInfo = sourceInfos[i];
                var option = document.createElement('option');
                option.value = sourceInfo.id;
                if (sourceInfo.kind === 'video') {
                    option.text = sourceInfo.label || 'camera ' + (videoSelect.length + 1);
                    videoSelect.appendChild(option);
                } else {
                    console.log('Some other kind of source: ', sourceInfo);
                }
            }
        }

        if (typeof MediaStreamTrack === 'undefined') {
            alert('This browser does not support MediaStreamTrack.\n\nTry Chrome Canary.');
        } else {
            MediaStreamTrack.getSources(gotSources);
        }

        function successCallback(stream) {
            window.stream = stream; // make stream available to console
            videoElement.src = window.URL.createObjectURL(stream);
            videoElement.play();
        }

        function errorCallback(error){
            console.log('navigator.getUserMedia error: ', error);
        }

        function start(){
            if (!!window.stream) {
                videoElement.src = null;
                window.stream.stop();
            }
            var videoSource = videoSelect.value;
            var constraints = {
                audio: false,
                video: {
                    optional: [{sourceId: videoSource}]
                }
            };
            navigator.getUserMedia(constraints, successCallback, errorCallback);
        }

        videoSelect.onchange = start;

        start();

        // Take snapshot example

        // Put event listeners into place
        window.addEventListener("DOMContentLoaded", function() {
            // Grab elements, create settings, etc.
            var canvas = document.getElementById("canvas"),
            context = canvas.getContext("2d"),
            video = document.getElementById("video"),
            videoObj = { "video": true },
            errBack = function(error) {
                console.log("Video capture error: ", error.code); 
            };

        // Trigger photo take
        document.getElementById("snap").addEventListener("click", function() {
            $scope.$apply(function () {
                context.drawImage(video, 0, 0, 640, 480);
                $scope.showVideo = false;
                $scope.showSnap = true;
            });
        });

        // Save photo
        document.getElementById("save").addEventListener("click", function() {
            $scope.$apply(function () {
                var image = new Image();
                image.src = canvas.toDataURL("image/jpg");
                $scope.image = image.src;
                console.log($scope.image);
                $scope.showVideo = true;
                $scope.showSnap = false;
                //return image;
            });

        });
        document.getElementById("cancel").addEventListener("click", function() {
            $scope.$apply(function () {
                $scope.showVideo = true;
                $scope.showSnap = false;
            });
        });
    }, false);
    }
};
});

这是我的app.js:

var app = angular.module('cameraApp', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
         $routeProvider .when('/', {
             controller: 'CameraController',
             templateUrl: 'views/app.html'
         })
         .when('/login', {
             controller: 'LoginController',
             templateUrl: 'views/login.html'
         })
         .otherwise({redirectTo: '/login'});
}]);


app.controller('MainController', function($scope, $window) {
    console.log($window);
    console.log($scope);
});

app.controller('LoginController', function($scope) {

});

app.controller('CameraController', function($scope) {

});

这是我的index.html:

<!DOCTYPE html>
<html lang="en" ng-app="cameraApp">
<head>
    <meta charset="utf-8">
    <title>AngularCameraApp</title>
    <!--<link rel="stylesheet" href="style.css">-->
</head>
<body ng-controller="MainController">

    <ul>
        <li><a href="#/login">Login</a></li>
        <li><a href="#/">App</a></li>
    </ul>

    <div ng-view></div>

    <script src="js/lib/angular.min.js"></script>
    <script src="js/lib/angular-route.min.js"></script>
    <script src="js/app.js"></script>
    <script src="js/directives.js"></script>
</body>

非常感谢您提供任何帮助!

冈扎里

我终于做到了。我需要在答案中提出三点:解决方案,问题,错误/建议。我先提出解决方案,然后再编辑以添加其他部分。请在更新后重新阅读我的答案。

解决方案

首先,您可以看到这个工作的柱塞

我将您的点击函数移动到$ scope变量中,如下所示:

    $scope.snap = function() {
      console.log("coucou");
      var canvas = document.getElementById("canvas");
      context = canvas.getContext("2d");
      context.drawImage(video, 0, 0, 640, 480);
      $scope.showVideo = false;
      $scope.showSnap = true;
    }


    // Save photo
    $scope.save = function() {
          var image = new Image();
          image.src = canvas.toDataURL("image/jpg");
          $scope.image = image.src;
          console.log($scope.image);
          $scope.showVideo = true;
          $scope.showSnap = false;
    }
    $scope.cancel = function() {
      $scope.showVideo = true;
      $scope.showSnap = false;
    }

window.addEventListener(“ DOMContentLoaded”,function(){})之外

我在元素上添加了一些ng-click,以将其绑定到函数。

    <button ng-click="save()">Save Photo</button>

这就是全部。

问题

现在的问题是,为什么仅在使用路由后才出现此错误?

您必须知道使用

 window.addEventListener("DOMContentLoaded", function(){})

在AngularJS中不是一个好主意。

Angular将使用div加载第一页:index.html(在我的朋克中)

 <ng-view></ng-view>

html文件完全加载后,上面的功能将启动。但是该页面实际上并没有完全构建。您的DOM实际上已完全加载,但是angular将使用其路由系统将app.html(在我的插件中)添加到ng-view元素中。

当window.addEventListener(“ DOMContentLoaded”,function(){})首次运行时,这三个按钮不存在。因此,没有添加clicks事件。

错误/建议

我看到了许多不应在angularJS中完成的事情。我会告诉你什么,以及应该如何做。

1-操作DOM

在angular中,您不需要从javascript处理DOM。如果要这样做,请记住,使用本机angular指令可以满足您的所有需求。

在角度上,您应该看不到:

 document.getElementById("snap").addEventListener("click",
 window.addEventListener("DOMContentLoaded", 
 videoSelect.appendChild(option);
 document.createElement('option');

相反,您应该看到这种指令:

 //To launch a function on a click/change/focus/blur etc...
 <div ng-click="myfunction()"></div>
 <input ng-model="myvar" ng-change="function()">
 etc...

您可以在此简短的角度教程中找到所有需求

希望对您有帮助。

2-指令

指令的目的是向元素添加行为。在您的用例中,如果您不重复使用组件,那么重用指令是一个不错的选择,用它来制作指令并不是很有用。还请记住,自定义指令是虚假的朋友。大多数时候,您不需要他们以干净的方式做您想做的事情。

3-应用

在angular中,您只想尽可能地避免$ apply()。在某些情况下,它确实可以杀死性能,并且您90%的时间不需要它。

4-一种做自己想要的事的干净方法

我真的很想向您展示如何在插件中工作,但是要使您的指令适应整洁的方式,这需要太多的工作。这样,您应该将很多东西放到CameraService中(获取媒体流,启动它,停止它的功能等等),并且只需要将一些绑定绑定到您的控制器和HTML中就可以得到相同的结果。

另一种干净的方法是使用容器指令和一些指令在每个元素上添加所需的行为。但这需要对angularJS有一定的了解

希望对您有所帮助。如果您有任何问题,请随时提出。

编辑:回答评论中的问题

我将此添加到指令中。你可以看到它在这里工作

    $scope.$on('$locationChangeStart', function(event) {
        if (!!window.stream) {
            videoElement.src = null;
            window.stream.stop();
        }
    });

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

AngularJS自定义指令

来自分类Dev

ANgularjs:ng-repeat和嵌套的自定义指令

来自分类Dev

自定义ngTagsInput和autoComplete指令(AngularJS)

来自分类Dev

AngularJS和自定义方法/ HTML的指令

来自分类Dev

ANgularjs:ng-repeat和嵌套的自定义指令

来自分类Dev

使用自定义指令,ng-show和$ scope在Angularjs中隐藏/显示元素

来自分类Dev

如何在AngularJS中实现自定义格式和输入指令(解决超越范围的问题)?

来自分类Dev

使用自定义指令,ng-show和$ scope在Angularjs中隐藏/显示元素

来自分类Dev

angularjs自定义表单和字段指令:在FormController中找不到ngModelController

来自分类Dev

AngularJS-自定义指令中的点击访问

来自分类Dev

自定义指令模板中的AngularJS控制变量

来自分类Dev

在AngularJS自定义验证指令中调用异步服务

来自分类Dev

使用指令绑定angularjs中的自定义事件

来自分类Dev

AngularJS在自定义指令中包装ui选择

来自分类Dev

在自定义指令中绑定数据-AngularJS

来自分类Dev

在Angularjs自定义指令中获取属性的值

来自分类Dev

AngularJS指令中自定义HTML标记的后果

来自分类Dev

AngularJS-在自定义指令中更新变量

来自分类Dev

在Angularjs自定义指令中获取属性的值

来自分类Dev

angularjs自定义指令值更改

来自分类Dev

AngularJS自定义指令双向绑定

来自分类Dev

选择的AngularJS自定义指令

来自分类Dev

angularjs自定义指令重复属性

来自分类Dev

多个自定义指令angularjs

来自分类Dev

AngularJS:自定义指令内的ngView

来自分类Dev

AngularJS动态自定义指令问题

来自分类Dev

AngularJs 多个自定义指令失败

来自分类Dev

AngularJS:无法从自定义指令属性中检索值以在自定义指令中进行解析

来自分类Dev

自定义angularjs路由网址

Related 相关文章

  1. 1

    AngularJS自定义指令

  2. 2

    ANgularjs:ng-repeat和嵌套的自定义指令

  3. 3

    自定义ngTagsInput和autoComplete指令(AngularJS)

  4. 4

    AngularJS和自定义方法/ HTML的指令

  5. 5

    ANgularjs:ng-repeat和嵌套的自定义指令

  6. 6

    使用自定义指令,ng-show和$ scope在Angularjs中隐藏/显示元素

  7. 7

    如何在AngularJS中实现自定义格式和输入指令(解决超越范围的问题)?

  8. 8

    使用自定义指令,ng-show和$ scope在Angularjs中隐藏/显示元素

  9. 9

    angularjs自定义表单和字段指令:在FormController中找不到ngModelController

  10. 10

    AngularJS-自定义指令中的点击访问

  11. 11

    自定义指令模板中的AngularJS控制变量

  12. 12

    在AngularJS自定义验证指令中调用异步服务

  13. 13

    使用指令绑定angularjs中的自定义事件

  14. 14

    AngularJS在自定义指令中包装ui选择

  15. 15

    在自定义指令中绑定数据-AngularJS

  16. 16

    在Angularjs自定义指令中获取属性的值

  17. 17

    AngularJS指令中自定义HTML标记的后果

  18. 18

    AngularJS-在自定义指令中更新变量

  19. 19

    在Angularjs自定义指令中获取属性的值

  20. 20

    angularjs自定义指令值更改

  21. 21

    AngularJS自定义指令双向绑定

  22. 22

    选择的AngularJS自定义指令

  23. 23

    angularjs自定义指令重复属性

  24. 24

    多个自定义指令angularjs

  25. 25

    AngularJS:自定义指令内的ngView

  26. 26

    AngularJS动态自定义指令问题

  27. 27

    AngularJs 多个自定义指令失败

  28. 28

    AngularJS:无法从自定义指令属性中检索值以在自定义指令中进行解析

  29. 29

    自定义angularjs路由网址

热门标签

归档