Breaking: Version 2 improvements (fixes #29)#30
Breaking: Version 2 improvements (fixes #29)#30oliverfoster wants to merge 23 commits intomasterfrom
Conversation
|
Conflicts need resolved on this |
Logging improvements migrated from #26
|
Moved to resolve conflicts and brought in the logging improvements from #26 |
Corrected wording for clarity in IntersectionSet section.
|
|
…oved event trigger for 'scoring:reset' to `Lifecycle` for consistency. Questionable whether a public method to update scoring is required. No longer used directly in scoring plugins as was the case with v1.
… `IntersectionSet` rather than `ScoringSet` as this is only required for intersection queries.
js/ScoringSet.js
Outdated
| * @param {Backbone.Model} model | ||
| * @returns {number} | ||
| */ | ||
| getMinScoreByModel(model) { |
There was a problem hiding this comment.
If these functions, and those added by Joe, aren't used anywhere other than the logging code, can we move them out of the main ScoringSet API and into a helpers file? Or fold them into the places that they're called from? I don't see a need for multiple small functions when a single larger one would work.
This is almost 10 new main API functions, just for printing logs.
There was a problem hiding this comment.
Will look into offloading the logic into another class, similar to how objectives are handled, but the different methods were setup to allow subclass extensibility, so we can easily override just the bits that differ between sets.
There was a problem hiding this comment.
I don't see any use case for these beyond the logging stuff. Are you intending that the logging be overridden per set?
js/ScoringSet.js
Outdated
| return this.models.some(model => model.get('_isVisited')); | ||
| get isPartlyCorrect() { | ||
| if (!this.isSubmitted) return null; | ||
| return (this.correctness < this.maxCorrectness); |
There was a problem hiding this comment.
Returns true if correctness is 0.
js/ScoringSet.js
Outdated
| return this.isStarted && !this.isComplete; | ||
| get isIncorrect() { | ||
| if (!this.isSubmitted) return null; | ||
| return (!this.correctness && this.maxCorrectness); |
There was a problem hiding this comment.
Returns the maxCorrectness value if correctness equals 0.
js/Lifecycle.js
Outdated
| }, | ||
| // restart calls set.onStart when any intersecting model or set is reset | ||
| async restart(set) { | ||
| await set.onStart?.(); |
There was a problem hiding this comment.
Could this call set.onRestart?.() instead to distinguish between a first attempt and a restart attempt? An alternative would be to have a flag akin to how wasRestored is used, but two different methods seems like a cleaner option. Is there a specific reason why this wouldn't work or cause problems?
See https://github.com/adaptlearning/adapt-contrib-scoring/pull/30/changes#r3024196814 for some context.
In cases where a set may require start and restart to be the same, onRestart called also call onStart within the set. Even in the current AssessmentSet.onStart`, some of these methods probably only need to happen after a reset.
There was a problem hiding this comment.
I didn't see any difference when I was rewriting everything. Just that reset/restart is usually exactly the same behaviour as start. Start is always the beginning of the lifecycle and reset, although seemingly at the end, is always the beginning of the lifecycle. I removed the on restart phase to clarify that it is effectively starting again. If you need to keep state between attempts then that state should be kept and managed on the set and not in the lifecycle stuff, where it's just confusing. Reset is not a finished or complete.
…ds in `ScoringSet` to query its models rather rather than the single parent model (which isn't always populated in a set). Fixed issues when evaluating correctness.
…rt attempt. Marked lifecycle callback hooks as protected methods, as calling these externally defeats the benefits of the LifecycleRenderer.
…ntrib-scoringAssessment#17. Resolved reset issues as the objective needs to wait until the set has been reset before updating the score and status - adjusted methods and logic accordingly so score and status can be handled separately by the sets lifecycle methods.
…class to keep this logic separate from the `ScoringSet`.
| * Intentionally empty to prevent super Class event triggers | ||
| * @override | ||
| */ | ||
| onCompleted() {} |
There was a problem hiding this comment.
Do we need AdaptModelSet to be firing the scoring event triggers? Anything listening to events such as 'scoring:set:complete' will be triggered every time one of these models is completed. Are we ever likely to use something like https://github.com/adaptlearning/adapt-contrib-scoringResults for these type of sets?
Leaving them in means we have a chatty scoring event system, which will probably not be utilised for these models. As these sets are only really needed to allow the queries and intersections to work, I would probably prevent them from firing the events to match v1, but happy to leave them in if it offers us more flexibility without compromising performance.
There was a problem hiding this comment.
I think leave to them in; it's a valid event to fire as a set is being completed.
| _updateQueue(model) { | ||
| this._queuedChanges.push(model); | ||
| this._debouncedUpdate(); | ||
| getSetById(id) { |
There was a problem hiding this comment.
This is no longer exported. It can obviously be used via Adapt.scoring.getSetById, but should we make all of these types of methods utility functions that can be imported by plugins as required?
Currently we have a mixture of those that can only be referenced via Adapt.scoring and others which can be both imported individually or used via the scoring object. Do we need both, or just use imports?
There was a problem hiding this comment.
They should be exported, yes.
Adapt.scoring references are easy to grab from the console. This can be handy for debugging.
| /** @override */ | ||
| onCompleted() { | ||
| if (this.isIntersectedSet) return; | ||
| Adapt.trigger('scoring:complete', Adapt.scoring); |
There was a problem hiding this comment.
Should use this as an argument rather than Adapt.scoring, to provide the correct context to listeners such as https://github.com/adaptlearning/adapt-contrib-core/blob/2c6ef07f8bfe5fe4dd317e4d0dad899cbd1f86e1/js/tracking.js#L93.
| async restore() { | ||
| const sets = getAllSets(); | ||
| await this.renderer.render.restore(sets); | ||
| Adapt.trigger('scoring:restored', this.scoring); |
There was a problem hiding this comment.
As per https://github.com/adaptlearning/adapt-contrib-scoring/pull/30/changes#r3079115424, the event triggers on this file should include the TotalSets context unless we change the way the listeners currently work.
fixes #29
Fix
Update
isAvailableInHierarchyto account for detached models.orderavailableComponentsetcset,getSet.., etcStateandObjectiveapisinit,restore,start,reset,restart,visit,leaveandupdate, fully integrating adapt-contrib-modifiersNew
TotalSetsto replace the set behaviour on the mainAdapt.scoringAPIBreaking