钉钉页面跳转_钉钉开发之应用页面跳转到外部页面时参数传递问题

在做用户免登功能的时候遇到了一个困扰挺久的问题,在钉钉提供的示例代码中,已经为我们写出了获取到userid的方法,并且将值设置到了data里面

data:{//设置值 在login.axml上

corpId: '',

authCode:'',

userId:'',

userName:'',

hideList: false,//列表隐藏

}

dd.getAuthCode({//获得用户免登码

success:(res)=>{//如果成功获取,给个res(Result结果)对象,并且执行dd.httpRequest({})请求方法

this.setData({//设置上面有定义的具体data数据

authCode:res.authCode//将authCode值设置为获取到的值

})

//dd.alert({content: "step1"});

dd.httpRequest({//执行dd.httpRequest方法

url: url,//设置请求地址

method: 'POST',//请求方式

data: {//传递的数据

authCode: res.authCode//获取到的authCode值,设置给authCode变量

},

dataType: 'json',//数据类型JSON

success: (res) => {//如果dd.httpRequest()方法请求成功,即获取到了userid和username

// dd.alert({content: "step2"});

console.log('success----',res)//控制台打印出来

let userId = res.data.result.userId;//路径在控制台里有体现

let userName = res.data.result.userName;

this.setData({//设置上面有定义的具体data数据

userId:userId,

userName:userName,

hideList:false

})

},

fail: (res) => {//如果dd.httpRequest()方法请求失败

console.log("httpRequestFail---",res)//控制台打印信息

dd.alert({content: JSON.stringify(res)});//login.axml页面弹出错误信息

},

complete: (res) => {//调用结束的回调函数,(请求成功、失败都会执行)

dd.hideLoading();

}

});

},

fail: (err)=>{//如果获取用户免登码失败

// dd.alert({content: "step3"});

dd.alert({//弹出错误信息

content: JSON.stringify(err)

})

}

})

而我要做的事就是拿到这个userid值,并且传递给我要链接到的地址作为参数。

这里我有两个页面,First和login页面  都在page的子目录下,两个文件夹同级。

First页面是用来放外部页面的。而login页面是一开始加载显示的页面,获取userid的函数执行也在这个页面的js里。

钉钉开发文档提供了一个组件web-view 可以用来连接到外部地址。但是里面的参数src不能直接用+的方式直接拼接,经过摸索,可以使用{{}}传值的方式:

①先在First.axml页面将要访问的地址设置成这种方式

②在对应的First.js页面Page里配置:Page({

data: {//data里的数据只能传递给axml页面中有用{{}}来设置值的

a:'https://www.',

b:'baidu',

c:'.com',

这种方式就可以实现参数的拼接。a、b、c里面的数据可以自己按照自己的需求来写。

这里有个很重要的不能忽视的点!!因为钉钉E应用只允许应用内的页面跳转,我们刚才说的跳转到外部页面实际上也是跳转到钉钉E应用的另一个页面罢了,只是说它将外部页面自动铺满E应用的页面。即在login.axml页面使用dd.navigateTo方法dd.navigateTo({//跳转到另一个页面

url:'../First/First'

})

而这个页面的地址链接到的就是上面我们在另一个页面用web-view 方法设置的地址。

我如何取出login.js 中data 里面的userid并将它作为参数传递给First页面?

方法不难,在要跳转的路径上使用?来增加参数:dd.navigateTo({//跳转到另一个页面

url:'../First/First?userId='+this.data.userId

})

这样子,当我们触发这个跳转事件时,就会将userId的值一起传递到要接收的页面。

那First页面如何接收传递过来的值?

我们在First.js页面的onLoad方法中接收:onLoad(query) {

this.setData({

userId:query.userId

})

}

这样子,在First页面加载的时候,就会将login页面传递过来的userid值设置到data中。

这里有个很细节的地方!!!!

我们在从login页面跳转到First页面(外部页面)时,我们刚才是用的dd.navigateTo({//跳转到另一个页面

url:'../First/First?userId='+this.data.userId

})

这种方法。用这个方法我们要保证的首先是:this.data.userId是已经有值的。否则你传递的只是一个空值。所以我们应该在login这个页面刚开始加载的时候就要实现获取到userid这个方法了。即在onLoad()方法里去实现:onLoad(){//页面加载时执行的方法

dd.showLoading();//显示加载效果

dd.getAuthCode({//获得用户免登码

success:(res)=>{//如果成功获取,给个res(Result结果)对象,并且执行dd.httpRequest({})请求方法

this.setData({//设置上面有定义的具体data数据

authCode:res.authCode//将authCode值设置为获取到的值

})

//dd.alert({content: "step1"});

dd.httpRequest({//执行dd.httpRequest方法

url: url,//设置请求地址

method: 'POST',//请求方式

data: {//传递的数据

authCode: res.authCode//获取到的authCode值,设置给authCode变量

},

dataType: 'json',//数据类型JSON

success: (res) => {//如果dd.httpRequest()方法请求成功,即获取到了userid和username

// dd.alert({content: "step2"});

console.log('success----',res)//控制台打印出来

let userId = res.data.result.userId;//路径在控制台里有体现

let userName = res.data.result.userName;

this.setData({//设置上面有定义的具体data数据

userId:userId,

userName:userName,

hideList:false

})

},

fail: (res) => {//如果dd.httpRequest()方法请求失败

console.log("httpRequestFail---",res)//控制台打印信息

dd.alert({content: JSON.stringify(res)});//login.axml页面弹出错误信息

},

complete: (res) => {//调用结束的回调函数,(请求成功、失败都会执行)

dd.hideLoading();

}

});

},

fail: (err)=>{//如果获取用户免登码失败

// dd.alert({content: "step3"});

dd.alert({//弹出错误信息

content: JSON.stringify(err)

})

}

})

let _this = this;//定义_this变量,设置为当前页面

this.setData({//设置上面有定义的具体data数据

corpId: app.globalData.corpId

})

//dd.alert({content: "step1"});

}

总结:

这样实现后,我们的效果就是在第一个页面加载完成的时候,我们已经实现了获取userid的方法,并且将值设置到了data当中。当我们触发跳转事件(比如设置一个按钮,触发点击事件实现跳转)时,能够将data中的值作为参数一同传递给另一个页面,同时另一个页面接收成功后,把这个值设置到自己页面的data中。如此访问外部地址传参的问题就成功解决了!

在这个过程中我遇到了一个很细节很细节的问题:我可不可以在访问外部地址的这个页面(First)的js里自己获取userid然后设置到自己的data里面?这样是不是更简单?

告诉你这是不行的!!!因为我就是踩这坑的!

原因是什么?

我如果在First这个页面的js函数里获取userid,这个是可以获取得到的,并且也可以设置到data里。要实现免登肯定是要在点击跳转时就要获取到userid并传给地址作为参数。 所以你至少必须要把获取的方法写在onload方法里面。理想状况下,你会这样认为:当点击跳转时,页面加载的时候实现了获取userid的方法获取到了id,并已经设置到页面的data里面。访问地址的时候这串参数也已经传递上去了。

但!这里不是你想的那样!你会发现不论怎么样都不是预想的效果的。如果你在onload方法里的开头添加一句dd.alert({userid});

结果就会很清楚。 ——页面加载完后,这个函数才执行!也就是说页面已经显示了,才会弹出框。这就是本质问题所在。

我们写在同一个页面的js里,获取userid的函数执行实际上是比页面加载来得慢的(虽然我们将方法写在onload()里面,按道理是在页面加载的时候就要处理完,但因为函数执行获取userid是需要先获取免登码,然后再请求到后端处理,处理完才返回结果。这个过程是有一定时间的,所以没办法在我们触发跳转事件后的第一时间就能获取到userid并设置到data里面。所以data里面的userid是没有值的!)

而如果我们用两个页面传参的方式,在login页面加载完后,获取到userid了,并设置到了data上去。这时把这个userid传过去First页面,在First.js里的onload()方法就不需要再请求了,只需要将获取到的userid设置到data里就行了。所以时间就同步了。

简单来说就是时间差导致的不同步问题。

以上观点只是我自己的想法,如果有错误的希望指出,感谢!


版权声明:本文为weixin_39554290原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。