Based on angular6, using third-party js to call the phone camera, photo album applications encountered pitfalls

The project I did recently was developed using Angular 6. What I did was to separate the front and back ends. I originally did the back-end, but I was pulled into the front-end. I have never used Angular before. I think I will definitely do it in the development process. Encountered pits one after another, there is no way, one can solve one after another.

Among them, calling mobile phone albums and cameras is one of them, and the js of a third-party partner is used. Not much nonsense, and directly explain the problems encountered;

One, the first is how the angular project introduces external JS files

In fact, there are a lot of solutions to this problem on the Internet. The main thing is to put the file in the assert directory and add configuration in angular.json, which will not be discussed in detail here;

Second, call the method provided by external js, the variables in this class cannot be obtained in the callback function

After selecting a photo or after taking a photo, the callback function will return the picture object, which has a value of the base64-encoded pic attribute and the file name fileName attribute, so I need to pass the base64 encoding to the img tag in the callback. During the transfer process, I found that the value bound to img is always empty. After checking several times, the base64 value is also passed to the variable in ts. However, if it is printed out, the value is empty. After consulting others, I know that it is a callback. The reason for the method, the this. variable in the callback method may not be in ts, the method will think it is a variable in the callback, so finally the bind method is added behind the method body to get the variables in the class. The code is as follows:

iPortal.getCamera().takePicture(function (picture) {
        // 调用拍照功能       
          this.pictures.push(picture.pic);
        // 将图片对象放入另一个数组  上传图片使用
        this.pictBase64.push(picture);
        // 及时更新图片数组,选择后显示在页面
        this.zone.run(() => {
          setTimeout(() => this.pictures = this.pictures, this.pictBase64 = this.pictBase64, 10);
          // setTimeout(() => this.pictBase64 = this.pictBase64, 10);
        });
      }.bind(this),
        function (err) {
          this.toastTip(err);
        }.bind(this),
        1);

3. IOS can display base64 encoded pictures, but Android can’t.

After you can assign values ​​to the bind variables in the callback, I found that the iPhone can display pictures, but Android can’t display them. After studying for a long time, I still haven’t found the problem. In the end, I can only print the base64 codes of the two mobile phones. See what the difference is. Sure enough, the code displayed on the Apple phone is very compact and has no spaces. However, what about Android:

 

There are line breaks or spaces, so we can only get rid of these in the encoding, and we have to distinguish the type of the current device. Is it Apple? Or android

iPortal.getCamera().takePicture(function (picture) {
        // 调用拍照功能
        let u = navigator.userAgent;
        // 当前设备信息
        let device = '';
        if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {
          // 安卓手机
          device = 'Android';
          let codeArr = picture.pic;
          // 图片不超过9张的情况下放入数组
          this.pictures.push(codeArr.replace(/\s*/g, ''));

        } else if (u.indexOf('iPhone') > -1) {
          // 苹果手机
          device = 'iPhone';
          // 图片不超过9张的情况下放入数组
          this.pictures.push(picture.pic);
        }
        // 将图片对象放入另一个数组  上传图片使用
        this.pictBase64.push(picture);
        // 及时更新图片数组,选择后显示在页面
        this.zone.run(() => {
          setTimeout(() => this.pictures = this.pictures, this.pictBase64 = this.pictBase64, 10);
          // setTimeout(() => this.pictBase64 = this.pictBase64, 10);
        });
      }.bind(this),
        function (err) {
          this.toastTip(err);
        }.bind(this),
        1);

codeArr.replace(/\s*/g,'') is to delete spaces and newlines in the code;

Fourth, data update and strong loading

After the photo is selected, the img tag cannot display the image immediately. You need to click on another blank space before the image comes out. This paragraph in the code solves this problem:

this.zone.run(() => {
          setTimeout(() => this.pictures = this.pictures, this.pictBase64 = this.pictBase64, 10);
          // setTimeout(() => this.pictBase64 = this.pictBase64, 10);
        });

Give a delayed load and update the data in the variable in time to solve the problem;

Guess you like

Origin blog.csdn.net/tonglei111/article/details/86472841