使用JS将树脑移植到Flutter网站中时,出现以下错误“ options.selector or options.container必须引用有效的DOM节点”。 [英] braintree into fliutter web using JS got this error "options.selector or options.container must reference a valid DOM node"

查看:222
本文介绍了使用JS将树脑移植到Flutter网站中时,出现以下错误“ options.selector or options.container必须引用有效的DOM节点”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试将Braintree付款网关实施到混乱的网络中。
Braintree仍然没有 flutter web 的SDK。因此,尝试实施他们的javascript SDK。



这是我的js文件

  functionpayment(auth){
var button = document.querySelector('submit-button');
console.log(auth);
console.log(button);
braintree.dropin.create({
授权:auth,
容器:'dropin-container'
},功能(createErr,实例){
console.log (createErr);
console.log(instance);
button.addEventListener('click',function(){
instance.requestPaymentMethod(function(requestPaymentMethodErr,payload){
//将有效负载.nonce提交到您的服务器
返回有效负载.nonce
});
});
});
}

从dart调用此js函数。这是完整的dart代码。

  @JS()
库my_script;

导入‘dart:html’;
导入 dart:js_util;

导入 package:carbonbins / model / model.dart;
导入的 package:carbonbins / pages / navigation.gr.dart;
import‘package:carbonbins / utils / image_helper.dart’;
导入的 package:flutter / material.dart;
导入 dart:ui为ui;

导入 package:js / js.dart;
作为 js导入 package:js / js.dart;

@JS()
外部无效initBraintree(auth);

@JS()
外部字符串付款(auth);

类PaymentPage扩展了StatefulWidget {
final UserModel userModel;

PaymentPage({@ required this.userModel});

@override
_PaymentPageState createState()=> _PaymentPageState();
}

类_PaymentPageState扩展了State< PaymentPage> {

String auth = sandbox _.....;

void getButton(){
var htmlL =< div id = checkout-message>< / div>
< div id = dropin-container< / div>
< button id = submit-button> Submit payment< / button>;

//忽略:undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'payment-container',
(int viewId)=> DivElement()
..appendHtml(htmlL)
..style.border ='none');

print(HtmlElementView(
viewType: dropin-container,
));
}

void setupDropin(){
print(auth);
var status = Payment(auth);
print( Status:$ status);
}

@override
void initState(){
getButton();
setupDropin();
super.initState();
}

@override
小部件构建(BuildContext上下文){
return Scaffold(
body:Container(
width:MediaQuery.of (上下文).size.width,
子级:列(
子级:< Widget> [
SizedBox(
高度:100,
),
容器(
宽度:500.0,
高度:300.0,
子对象:HtmlElementView(
viewType: payment-container,
),

],
),
),
);
}

运行此代码时,我在屏幕上仅看到提交按钮。从Web控制台收到此错误,

  options.selector或options.container必须引用有效的DOM节点。 

如何将Braintree付款集成到 flutter网站? p>

或可在波动网络中运行的任何其他国际支付网关。

解决方案


技术免责声明 :flutter-web处于测试版,我不建议将其与任何付款服务一起使用。


HtmlElementView 小部件添加了此内容。它的所有元素都变成了影子域,全局javascript上下文无法直接访问它。在github上查看此问题



解决方案是将 DivElement 引用传递给外部js函数。例如在您的情况下



在build方法之外创建div元素并保存引用,例如initSate

  
DivElement paymentDiv;

@override
initState(){

//始终在逻辑其余部分之前调用。
super.initState();

var htmlL =< div id = checkout-message>< / div>
< div id = dropin-container>< / div>
< button id = submit-button>提交付款< / button>;
paymentDiv = DivElement()
..appendHtml(htmlL)
..style.border ='none');
//剩余逻辑

}

然后在您的构建中/ other方法将此元素传递给 registerViewFactory 方法。

  //忽略:undefined_prefixed_name 
ui.platformViewRegistry.registerViewFactory(
'payment-container',
(int viewId)=> paymentDiv;

设置JS互操作以接受动态参数。

  @JS()
外部字符串付款(动态身份验证);

重写您的Javascript以直接使用此元素引用。例如

 功能付款(授权){
var button = auth;
//剩余逻辑
}


Trying to implement Braintree payment gateway into flutter web. Still no SDK for flutter web from Braintree. So trying to implement their javascript SDK.

Here is my js file

function payment(auth){
    var button = document.querySelector('submit-button');
    console.log(auth);
    console.log(button);
    braintree.dropin.create({
      authorization: auth,
      container: 'dropin-container'
    }, function (createErr, instance) {
        console.log(createErr);
        console.log(instance);
         button.addEventListener('click', function () {
            instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
              // Submit payload.nonce to your server
              return payload.nonce
            });
         });
    });
}

Calling this js function from dart. Here is the complete dart code.

@JS()
library my_script;

import 'dart:html';
import 'dart:js_util';

import 'package:carbonbins/model/model.dart';
import 'package:carbonbins/pages/navigation.gr.dart';
import 'package:carbonbins/utils/image_helper.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;

import 'package:js/js.dart';
import 'package:js/js.dart' as js;

@JS()
external void initBraintree(auth);

@JS()
external String payment(auth);

class PaymentPage extends StatefulWidget {
  final UserModel userModel;

  PaymentPage({@required this.userModel});

  @override
  _PaymentPageState createState() => _PaymentPageState();
}

class _PaymentPageState extends State<PaymentPage> {

  String auth = "sandbox_.....";

  void getButton() {
    var htmlL = """<div id="checkout-message"></div>
        <div id="dropin-container"></div>
    <button id="submit-button">Submit payment</button>""";

    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
        'payment-container',
        (int viewId) => DivElement()
          ..appendHtml(htmlL)
          ..style.border = 'none');

    print(HtmlElementView(
      viewType: "dropin-container",
    ));
  }

  void setupDropin() {
    print(auth);
    var status = payment(auth);
    print("Status: $status");
  }

  @override
  void initState() {
    getButton();
    setupDropin();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,
        child: Column(
          children: <Widget>[
            SizedBox(
              height: 100,
            ),
            Container(
              width: 500.0,
              height: 300.0,
              child: HtmlElementView(
                viewType: "payment-container",
              ),
            )
          ],
        ),
      ),
    );
  }

When I run this code, I see only the submit button in the screen. Got this error from web console,

"options.selector or options.container must reference a valid DOM node."

How can I integrate the Braintree payment into the flutter web?

or any other international payment gateway that works in flutter web.

解决方案

Technical Disclaimer: flutter-web is in beta and I would not recommend it to be used with any payment service. This might lead to critical issues and not advisable.

The HtmlElementView widget adds all its elements into shadowdom which is not directly accessible for the global javascript context. Check this issue here in github.

The solution would be to pass the DivElement reference to the external js function. For e.g. in your case

Create the div element out side the build method and hold a reference, like in initSate


DivElement paymentDiv;

@override
initState(){

// always call before rest of the logic.
super.initState();

var htmlL = """<div id="checkout-message"></div>
        <div id="dropin-container"></div>
    <button id="submit-button">Submit payment</button>""";
paymentDiv=  DivElement()
          ..appendHtml(htmlL)
          ..style.border = 'none');
// remaining logic

}

Then in your build/other method pass this element for the registerViewFactory method.

// ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
        'payment-container',
        (int viewId) => paymentDiv;

Set you JS interop to accept dynamic parameter.

@JS()
external String payment(dynamic auth);

Rewrite you Javascript to directly work with this element reference. e.g

function payment(auth){
    var button = auth;
    // Remaining logic
}

这篇关于使用JS将树脑移植到Flutter网站中时,出现以下错误“ options.selector or options.container必须引用有效的DOM节点”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆